Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix CAVOK propagating BECMG upon encountering conflicting conditions #38

Merged
merged 1 commit into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/forecast/forecast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ function hydrateWithPreviousContextIfNeeded(
forecast: Forecast,
context: Forecast | undefined
): Forecast {
// BECMG is the only forecast type that inherits old conditions
// Anything else starts anew
if (forecast.type !== WeatherChangeType.BECMG || !context) return forecast;

// Remarks should not be carried over
Expand All @@ -202,6 +204,15 @@ function hydrateWithPreviousContextIfNeeded(
// vertical visibility should not be carried over, if clouds exist
if (forecast.clouds.length) delete context.verticalVisibility;

// CAVOK should not propagate if anything other than wind changes
if (
forecast.clouds.length ||
forecast.verticalVisibility ||
forecast.weatherConditions.length ||
forecast.visibility
)
delete context.cavok;

forecast = {
...context,
...forecast,
Expand Down
98 changes: 93 additions & 5 deletions tests/forecast/forecast.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,11 +227,11 @@ TAF KMSN 142325Z 1500/1524 25014G30KT P6SM VCSH SCT035 BKN070
test("another TAF", () => {
const taf = parseTAF(
`
TAF
AMD KMSN 152044Z 1521/1618 24009G16KT P6SM SCT100
TEMPO 1521/1523 BKN100
FM160000 27008KT P6SM SCT150
FM160300 30006KT P6SM FEW230
TAF
AMD KMSN 152044Z 1521/1618 24009G16KT P6SM SCT100
TEMPO 1521/1523 BKN100
FM160000 27008KT P6SM SCT150
FM160300 30006KT P6SM FEW230
FM161700 30011G18KT P6SM BKN050
`,
{ issued: new Date("2022/04/15 21:46") }
Expand All @@ -243,6 +243,94 @@ TAF KMSN 142325Z 1500/1524 25014G30KT P6SM VCSH SCT035 BKN070
expect(forecast.end).toEqual(new Date("2022-04-16T18:00:00.000Z"));
});

describe("should handle CAVOK and", () => {
test("propagate if only wind changes", () => {
const taf = parseTAF(
`
TAF TAF EHAM 311720Z 3118/0124 12012KT CAVOK
BECMG 3121/3124 17017KT
BECMG 0103/0106 21025G35KT
`,
{ issued: new Date("2022/04/15 21:46") }
);
const forecast = getForecastFromTAF(taf);

expect(forecast.forecast[0].cavok).toBeTruthy();
expect(forecast.forecast[1].cavok).toBeTruthy();
expect(forecast.forecast[2].cavok).toBeTruthy();
});

test("not propagate if weather changes", () => {
const taf = parseTAF(
`
TAF TAF EHAM 311720Z 3118/0124 12012KT CAVOK
BECMG 3121/3124 17017KT
TEMPO 3123/0102 5000 RADZ SCT014 BKN018
TEMPO 0102/0111 7000 -SHRA SCT020TCU BKN025
BECMG 0103/0106 21025G35KT
TEMPO 0106/0109 23028G42KT
BECMG 0110/0113 21020G30KT -SHRA
BECMG 0117/0120 20015G25KT
TEMPO 0117/0124 22023G33KT 5000 SHRA SCT018CB BKN022
`,
{ issued: new Date("2022/04/15 21:46") }
);
const forecast = getForecastFromTAF(taf);

expect(forecast.forecast[0].cavok).toBeTruthy(); // 12012KT CAVOK
expect(forecast.forecast[1].cavok).toBeTruthy(); // BECMG 3121/3124 17017KT
expect(forecast.forecast[2].cavok).toBeFalsy(); // TEMPO 3123/0102 5000 RADZ SCT014 BKN018
expect(forecast.forecast[3].cavok).toBeFalsy(); // TEMPO 0102/0111 7000 -SHRA SCT020TCU BKN025
expect(forecast.forecast[4].cavok).toBeTruthy(); // BECMG 0103/0106 21025G35KT
expect(forecast.forecast[5].cavok).toBeFalsy(); // TEMPO 0106/0109 23028G42KT
expect(forecast.forecast[6].cavok).toBeFalsy(); // BECMG 0110/0113 21020G30KT -SHRA
expect(forecast.forecast[7].cavok).toBeFalsy(); // BECMG 0117/0120 20015G25KT
expect(forecast.forecast[8].cavok).toBeFalsy(); // TEMPO 0117/0124 22023G33KT 5000 SHRA SCT018CB BKN022
});

test("not propagate if vertical visibility changes", () => {
const taf = parseTAF(
`
TAF TAF EHAM 311720Z 3118/0124 12012KT CAVOK
BECMG 3121/3124 17017KT VV001
`,
{ issued: new Date("2022/04/15 21:46") }
);
const forecast = getForecastFromTAF(taf);

expect(forecast.forecast[0].cavok).toBeTruthy();
expect(forecast.forecast[1].cavok).toBeFalsy();
});

test("not propagate if clouds changes", () => {
const taf = parseTAF(
`
TAF TAF EHAM 311720Z 3118/0124 12012KT CAVOK
BECMG 3121/3124 17017KT OVC050
`,
{ issued: new Date("2022/04/15 21:46") }
);
const forecast = getForecastFromTAF(taf);

expect(forecast.forecast[0].cavok).toBeTruthy();
expect(forecast.forecast[1].cavok).toBeFalsy();
});

test("not propagate if visibility changes", () => {
const taf = parseTAF(
`
TAF TAF EHAM 311720Z 3118/0124 12012KT CAVOK
BECMG 3121/3124 17017KT 5000
`,
{ issued: new Date("2022/04/15 21:46") }
);
const forecast = getForecastFromTAF(taf);

expect(forecast.forecast[0].cavok).toBeTruthy();
expect(forecast.forecast[1].cavok).toBeFalsy();
});
});

describe("getCompositeForecastForDate", () => {
const taf = parseTAF(
`
Expand Down