Skip to content

Commit 679dfef

Browse files
committed
notams + tests pass
1 parent 27ab00f commit 679dfef

31 files changed

+113713
-27
lines changed

.vscode/settings.json

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
22
"[typescriptreact]": {
3-
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
4-
"editor.codeActionsOnSave": {
5-
"source.organizeImports": true
6-
}
3+
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
4+
// "editor.codeActionsOnSave": {
5+
// "source.organizeImports": true
6+
// }
77
},
88
"files.exclude": {
99
"**/._*": true,
@@ -13,10 +13,10 @@
1313
"editor.defaultFormatter": "esbenp.prettier-vscode"
1414
},
1515
"[typescript]": {
16-
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
17-
"editor.codeActionsOnSave": {
18-
"source.organizeImports": true
19-
}
16+
"editor.defaultFormatter": "esbenp.prettier-vscode"
17+
// "editor.codeActionsOnSave": {
18+
// "source.organizeImports": true
19+
// }
2020
},
2121
"typescript.updateImportsOnFileMove.enabled": "always",
2222
"[yaml]": {

remix/app/domain/Notam/Notam.test.ts

+283
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
import { fold, right } from 'fp-ts/lib/Either';
2+
import { pipe } from 'fp-ts/lib/function';
3+
import { draw } from 'io-ts/lib/Decoder';
4+
import { Notam } from './Notam';
5+
import icao_notams from './notams-icao-fra-en';
6+
import notams from './notams-notamweb-fra-fr';
7+
import { foldRichNotam, RichNotam } from './RichNotam/RichNotam';
8+
import * as E from 'fp-ts/lib/Either';
9+
import { AiracData } from 'ts-aerodata-france';
10+
import currentCycle from 'ts-aerodata-france/build/jsonData/2022-11-03.json';
11+
import { NotamDate } from './NotamDate';
12+
import { Code, Modifier, Q, Subject } from './Q';
13+
import modifierTable from './Q/Code/modifierTable';
14+
import subjectTable from './Q/Code/subjectTable';
15+
import { frnotams } from './fr-notams';
16+
import notamsNotamwebFraFr from './notams-notamweb-fra-fr';
17+
import { NotamIdentifier } from './NotamIdentifier';
18+
19+
const fixture1 = `LFFA-R3561/21 NOTAMN
20+
Q) LFXX/QRTCA/ I/ BO/ W/490/550/4652N00536E307
21+
A) LFEE LFFF LFMM
22+
B) 2022 Jan 13 00:00 C) 2023 Jan 11 23:59
23+
E) TRANSIT D'UN DRONE DANS L'EST DE LA FRANCE - SUP AIP 281/21 :
24+
OBJET : CREATION, A TITRE TEMPORAIRE, D'UNE ZONE DANGEREUSE ET DE 3
25+
ZONES REGLEMENTEES.
26+
CE SUP AIP EST DISPONIBLE SUR WWW.SIA.AVIATION-CIVILE.GOUV.FR
27+
F) FL490
28+
G) FL550
29+
`;
30+
31+
const fixture2 = `
32+
LFFA-N149/22 NOTAMN
33+
Q) LFXX/QRRCA/ IV/ BO/ W/0/43/4726N00011W
34+
A) LFBB LFFF LFMM LFRR
35+
B) 2022-11-24T16:07:00Z C) 2022-11-25T00:59:00Z
36+
E) ZONES AIRFORCE RTBA ACT
37+
ZONE R139 CHER
38+
1607-0059:ACTIVE
39+
ZONE R142 NIEVRE
40+
1607-0059:ACTIVE
41+
ZONE R143 AUVERGNE
42+
1700-0059:ACTIVE
43+
ZONE R144 LOIRE
44+
1607-0059:ACTIVE
45+
ZONE R145 CREUSE
46+
1607-0059:ACTIVE
47+
ZONE R165 VIENNE
48+
1607-0059:ACTIVE
49+
F) SFC
50+
G) 4300FT AMSL
51+
`;
52+
53+
const fixture3 = `
54+
A4288/22 NOTAMN
55+
Q) LFRR/QFMXX/IV/BO /A /000/999/4709N00136W005
56+
A) LFRS B) 2209140933 C) PERM
57+
E) MET SERVICES MODIFIED :
58+
REF AIP FRANCE GEN 3.5.10, TABLE 2,'EQUIPMENTS SYSTEM AND PLACE'
59+
COLUMN 3, NANTES ATLANTIQUE
60+
READ:
61+
-TEMPS PRESENT: CAPTEUR DE TEMPS PRESENT (PARC)
62+
-VENT: AERONAUTIQUE (MOYEN ET MAX)
63+
-RVR/VISIBILITE: 3 DIFFUSOMETRES THR 03 (DOUBLE), MEDIAN,ET THR 21
64+
-NUAGES: 1 TNL APPROCHE 03 ET 1 TNL SEUIL 21
65+
-S.A AVEC DIFFUSION A LA TWR
66+
CREATED: 14 Sep 2022 09:34:00
67+
SOURCE: EUECYIYN
68+
`;
69+
70+
describe('Notam', () => {
71+
describe('lexer', () => {
72+
it('should lex properly', () => {
73+
expect(Notam.lexer.decode(fixture1)).toEqual(
74+
right({
75+
identifier: 'LFFA-R3561/21 NOTAMN',
76+
q: 'LFXX/QRTCA/ I/ BO/ W/490/550/4652N00536E307',
77+
a: 'LFEE LFFF LFMM',
78+
b: '2022 Jan 13 00:00',
79+
c: '2023 Jan 11 23:59',
80+
e: `TRANSIT D'UN DRONE DANS L'EST DE LA FRANCE - SUP AIP 281/21 :
81+
OBJET : CREATION, A TITRE TEMPORAIRE, D'UNE ZONE DANGEREUSE ET DE 3
82+
ZONES REGLEMENTEES.
83+
CE SUP AIP EST DISPONIBLE SUR WWW.SIA.AVIATION-CIVILE.GOUV.FR`,
84+
f: 'FL490',
85+
g: 'FL550',
86+
}),
87+
);
88+
});
89+
});
90+
describe('decoder', () => {
91+
it('fixture1', () => {
92+
expect(Notam.decoder.decode(fixture1)).toEqual(
93+
right(
94+
new Notam({
95+
identifier: new NotamIdentifier({
96+
notamId: 'LFFA-R3561/21',
97+
type: 'NOTAMN',
98+
parentNotamId: null,
99+
}),
100+
a: 'LFEE LFFF LFMM',
101+
b: new NotamDate({
102+
s: '2022 Jan 13 00:00',
103+
date: new Date('2022-01-13T00:00:00.000Z'),
104+
est: false,
105+
}),
106+
c: new NotamDate({
107+
s: '2023 Jan 11 23:59',
108+
date: new Date('2023-01-11T23:59:00.000Z'),
109+
est: false,
110+
}),
111+
e: `TRANSIT D'UN DRONE DANS L'EST DE LA FRANCE - SUP AIP 281/21 :
112+
OBJET : CREATION, A TITRE TEMPORAIRE, D'UNE ZONE DANGEREUSE ET DE 3
113+
ZONES REGLEMENTEES.
114+
CE SUP AIP EST DISPONIBLE SUR WWW.SIA.AVIATION-CIVILE.GOUV.FR`,
115+
f: 'FL490',
116+
g: 'FL550',
117+
q: new Q({
118+
code: new Code({
119+
modifier: new Modifier({ ...modifierTable.CA, code: 'CA' }),
120+
subject: new Subject({ ...subjectTable.RT, code: 'RT' }),
121+
}),
122+
target: 'LFXX',
123+
traffic: { categories: ['I'] },
124+
}),
125+
}),
126+
),
127+
);
128+
});
129+
it.skip('fixture2', () => {
130+
expect(
131+
pipe(
132+
Notam.decoder.decode(fixture2),
133+
E.foldW(draw, (a) => a),
134+
),
135+
).toEqual({});
136+
});
137+
it('fixture3', () => {
138+
expect(
139+
E.isRight(
140+
pipe(
141+
Notam.decoder.decode(fixture3),
142+
E.mapLeft((e) => {
143+
console.error(draw(e));
144+
return e;
145+
}),
146+
// E.foldW(draw, (a) => a),
147+
),
148+
),
149+
).toEqual(true);
150+
});
151+
});
152+
describe('examples', () => {
153+
it('NOTAMWEB-FR', () => {
154+
const SEP = '\nLFFA';
155+
notamsNotamwebFraFr
156+
.split(SEP)
157+
.map((s) => SEP + s)
158+
.map((s) => ({ s, d: Notam.decoder.decode(s) }))
159+
.map(({ s, d }) =>
160+
pipe(
161+
d,
162+
fold(
163+
(e) => {
164+
console.error(draw(e));
165+
},
166+
(n) => {
167+
// console.log(
168+
// `${
169+
// n.identifier
170+
// }\nDescription: ${n.q?.code.subject.toString()}: ${n.q?.code.modifier.toString()}\n${
171+
// n.q?.target
172+
// }\n${n.e}\n${n.b.toString()} => ${n.c}\n${n.d}`,
173+
// );
174+
},
175+
),
176+
),
177+
);
178+
});
179+
it('FRENCH-METARS', () => {
180+
const SEP = '\n\n';
181+
frnotams
182+
.split(SEP)
183+
.map((s) => SEP + s)
184+
.map((s) => ({ s, d: Notam.decoder.decode(s) }))
185+
.map(({ s, d }) =>
186+
pipe(
187+
d,
188+
fold(
189+
(e) => {
190+
console.error(draw(e));
191+
},
192+
(n) => {
193+
// console.log(
194+
// `${
195+
// n.identifier
196+
// }\nDescription: ${n.q?.code.subject.toString()}: ${n.q?.code.modifier.toString()}\n${
197+
// n.q?.target
198+
// }\n${n.e}\n${n.b.toString()} => ${n.c}\n${n.d}`,
199+
// );
200+
},
201+
),
202+
),
203+
);
204+
});
205+
it('ICAO', () => {
206+
icao_notams
207+
.map((s) => ({ s, d: Notam.decoder.decode(s.all) }))
208+
.map(({ s, d }) =>
209+
pipe(
210+
d,
211+
fold(
212+
(e) => {
213+
console.error(draw(e));
214+
console.log(s.all);
215+
},
216+
function (n) {
217+
// return console.log(
218+
// `${n.identifier}\nDescription: ${n.q?.code.subject.description}: ${n.q?.code.modifier.description}\n${n.q?.target}\n${n.e}\n${n.b} => ${n.c}\n${n.d}`
219+
// );
220+
},
221+
),
222+
),
223+
);
224+
});
225+
it('ICAO PJE', () => {
226+
icao_notams
227+
.map((s) => ({
228+
s,
229+
n: pipe(
230+
Notam.decoder.decode(s.all),
231+
fold(
232+
(e) => {
233+
// console.error(draw(e));
234+
return null;
235+
},
236+
(n) => n,
237+
),
238+
),
239+
}))
240+
.filter(({ s, n }) => n !== null)
241+
.filter(({ n }) => n?.q.code.subject.code === 'WP')
242+
// .filter(({ s }) => s.all.match(/NR ?(\d|[A-Z])*/g))
243+
// .filter(({ n }) => n?.q.code.codeString === 'RRCA')
244+
.map(function ({ s, n }) {
245+
// return console.log(
246+
// `${n?.q.code.toString()}\n${s.all}\n${n?.b.toString()} => ${n?.c}\n${n?.d}`
247+
// );
248+
});
249+
});
250+
it('ICAO PJE', async () => {
251+
const allNotams: Notam[] = [];
252+
253+
const airacData = await AiracData.loadCycle(currentCycle);
254+
255+
// // To display them on the map
256+
// allNotams.map((n) =>
257+
// foldRichNotam({
258+
// rtbaNotam: (n: RtbaNotam) => {
259+
// // display them...
260+
// },
261+
// })(n),
262+
// );
263+
icao_notams.map((s) => ({
264+
s,
265+
n: pipe(
266+
s.all,
267+
Notam.decoder.decode,
268+
E.chain(RichNotam.decoder(airacData).decode),
269+
E.map(
270+
foldRichNotam({
271+
pje: ({ zones }) => {
272+
// console.log(zones);
273+
},
274+
rtba: ({ zones }) => {
275+
// console.log(zones);
276+
},
277+
}),
278+
),
279+
),
280+
}));
281+
});
282+
});
283+
});

0 commit comments

Comments
 (0)