Skip to content

Commit 121794c

Browse files
authored
Merge pull request #275 from airframesio/devin/1755126141-add-missing-tests-acars-decoder
Add missing tests: Label_SQ and Label_20_POS
2 parents 2fc0e4d + b7d6876 commit 121794c

2 files changed

Lines changed: 131 additions & 0 deletions

File tree

lib/plugins/Label_20_POS.test.ts

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { MessageDecoder } from '../MessageDecoder';
2+
import { Label_20_POS } from './Label_20_POS';
3+
4+
describe('Label_20_POS', () => {
5+
const decoder = new MessageDecoder();
6+
const plugin = new Label_20_POS(decoder);
7+
8+
const decode = (text: string) => {
9+
return plugin.decode({ text });
10+
};
11+
12+
it('decodes POS variation with 11 fields (coordinates only required)', () => {
13+
const text = 'POSN38160W077075,,211733,360,OTT,212041,,N42,19689,40,544';
14+
const res = decode(text);
15+
16+
expect(res.decoded).toBe(true);
17+
expect(res.decoder.name).toBe('label-20-pos');
18+
expect(res.decoder.decodeLevel).toBe('full');
19+
expect(res.formatted.description).toBe('Position Report');
20+
21+
expect(res.raw.preamble).toBe('POS');
22+
expect(res.raw.position).toBeDefined();
23+
expect(res.raw.position.latitude).toBeCloseTo(38.160, 3);
24+
expect(res.raw.position.longitude).toBeCloseTo(-77.075, 3);
25+
26+
const posItem = res.formatted.items.find(i => i.code === 'POS');
27+
expect(posItem).toBeDefined();
28+
expect(posItem.value).toContain('38.160');
29+
expect(posItem.value).toContain('77.075');
30+
});
31+
32+
it('decodes POS variation with 5 fields (coordinates only)', () => {
33+
const text = 'POSN38160W077075,,211733,360,OTT';
34+
const res = decode(text);
35+
36+
expect(res.decoded).toBe(true);
37+
expect(res.decoder.name).toBe('label-20-pos');
38+
expect(res.decoder.decodeLevel).toBe('full');
39+
expect(res.formatted.description).toBe('Position Report');
40+
41+
expect(res.raw.preamble).toBe('POS');
42+
expect(res.raw.position).toBeDefined();
43+
expect(res.raw.position.latitude).toBeCloseTo(38.160, 3);
44+
expect(res.raw.position.longitude).toBeCloseTo(-77.075, 3);
45+
46+
const posItem = res.formatted.items.find(i => i.code === 'POS');
47+
expect(posItem).toBeDefined();
48+
expect(posItem.value).toContain('38.160');
49+
expect(posItem.value).toContain('77.075');
50+
});
51+
52+
it('marks unknown variation as not decoded', () => {
53+
const text = 'POSUNKNOWN';
54+
const res = decode(text);
55+
56+
expect(res.decoded).toBe(false);
57+
expect(res.decoder.decodeLevel).toBe('none');
58+
expect(res.formatted.description).toBe('Position Report');
59+
});
60+
});

lib/plugins/Label_SQ.test.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { MessageDecoder } from '../MessageDecoder';
2+
import { Label_SQ } from './Label_SQ';
3+
4+
describe('Label_SQ', () => {
5+
const decoder = new MessageDecoder();
6+
const plugin = new Label_SQ(decoder);
7+
8+
const decode = (text: string) => {
9+
return plugin.decode({ text });
10+
};
11+
12+
it('decodes version 2 ARINC ground station squitter with coordinates and frequency', () => {
13+
const text = 'V2AA' + '0' + '1X' + 'A' + 'JFK' + 'KJFK' + '3' + '4075' + 'N' + '7398' + 'W' + 'V136975' + '/extra';
14+
const res = decode(text);
15+
16+
expect(res.decoded).toBe(true);
17+
expect(res.decoder.name).toBe('label-sq');
18+
expect(res.decoder.decodeLevel).toBe('full');
19+
20+
expect(res.raw.preamble).toBe(text.substring(0, 4));
21+
expect(res.raw.version).toBe('2');
22+
expect(res.raw.network).toBe('A');
23+
24+
expect(res.raw.groundStation).toBeDefined();
25+
expect(res.raw.groundStation.number).toBe('3');
26+
expect(res.raw.groundStation.iataCode).toBe('JFK');
27+
expect(res.raw.groundStation.icaoCode).toBe('KJFK');
28+
29+
expect(res.raw.groundStation.coordinates.latitude).toBeCloseTo(40.75, 5);
30+
expect(res.raw.groundStation.coordinates.longitude).toBeCloseTo(-73.98, 5);
31+
32+
expect(res.raw.vdlFrequency).toBeCloseTo(136.975, 6);
33+
34+
const items = res.formatted.items;
35+
expect(items.find(i => i.code === 'NETT')?.value).toBe('ARINC');
36+
expect(items.find(i => i.code === 'VER')?.value).toBe('2');
37+
expect(items.find(i => i.code === 'GNDSTN')?.value).toBe('KJFK3');
38+
expect(items.find(i => i.code === 'IATA')?.value).toBe('JFK');
39+
expect(items.find(i => i.code === 'ICAO')?.value).toBe('KJFK');
40+
expect(items.find(i => i.code === 'VDLFRQ')?.value).toContain('136.975');
41+
});
42+
43+
it('maps SITA network and handles absence of regex match gracefully', () => {
44+
const text = 'V2AS' + '0' + 'XXXXNOTMATCHING';
45+
const res = decode(text);
46+
47+
expect(res.decoded).toBe(true);
48+
expect(res.raw.version).toBe('2');
49+
expect(res.raw.network).toBe('S');
50+
51+
const items = res.formatted.items;
52+
expect(items.find(i => i.code === 'NETT')?.value).toBe('SITA');
53+
expect(items.find(i => i.code === 'VER')?.value).toBe('2');
54+
55+
expect(res.raw.groundStation).toBeUndefined();
56+
expect(res.raw.vdlFrequency).toBeUndefined();
57+
});
58+
59+
it('handles non-version-2 payloads (no regex path)', () => {
60+
const text = 'V1AA' + 'WHATEVER';
61+
const res = decode(text);
62+
63+
expect(res.decoded).toBe(true);
64+
expect(res.raw.version).toBe('1');
65+
expect(res.raw.network).toBe('A');
66+
67+
const items = res.formatted.items;
68+
expect(items.find(i => i.code === 'NETT')?.value).toBe('ARINC');
69+
expect(items.find(i => i.code === 'VER')?.value).toBe('1');
70+
});
71+
});

0 commit comments

Comments
 (0)