Skip to content

Commit

Permalink
Fix rvr parsing with slash separated trend (#106)
Browse files Browse the repository at this point in the history
Resolves #102
  • Loading branch information
fkrauthan authored Jan 2, 2025
1 parent 6a89fdd commit 256c37a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/command/metar/RunwayCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { ICommand } from "../metar";
export class RunwayCommand implements ICommand {
#genericRegex = /^(R\d{2}\w?\/)/;
#runwayMaxRangeRegex = /^R(\d{2}\w?)\/(\d{4})V(\d{3,4})([UDN])?(FT)?/;
#runwayRegex = /^R(\d{2}\w?)\/([MP])?(\d{4})([UDN])?(FT)?$/;
#runwayRegex = /^R(\d{2}\w?)\/([MP])?(\d{4})(?:([UDN])|(FT)(?:\/([UDN]))?)$/;
#runwayDepositRegex = /^R(\d{2}\w?)\/([/\d])([/\d])(\/\/|\d{2})(\/\/|\d{2})$/;

canParse(input: string): boolean {
Expand Down Expand Up @@ -42,7 +42,11 @@ export class RunwayCommand implements ICommand {
if (!matches) throw new UnexpectedParseError("Should be able to parse");

const indicator = matches[2] ? as(matches[2], ValueIndicator) : undefined;
const trend = matches[4] ? as(matches[4], RunwayInfoTrend) : undefined;
const trend = (() => {
if (matches[6]) return as(matches[6], RunwayInfoTrend);
if (matches[4]) return as(matches[4], RunwayInfoTrend);
})();

const unit = matches[5]
? as(matches[5], RunwayInfoUnit)
: RunwayInfoUnit.Meters;
Expand Down
23 changes: 23 additions & 0 deletions tests/command/metar/RunwayCommand.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,27 @@ describe("RunwayCommand", () => {
});
});
})();

(() => {
const code = "R36/4000FT/D"; // runway info north america style
const metar = { runwaysInfo: [] } as unknown as IMetar;

describe(code, () => {
test("canParse", () => {
expect(command.canParse(code)).toBe(true);
});

test("parse", () => {
command.execute(metar, code);

expect(metar.runwaysInfo).toHaveLength(1);
expect(metar.runwaysInfo[0]).toEqual({
name: "36",
minRange: 4000,
unit: RunwayInfoUnit.Feet,
trend: RunwayInfoTrend.Decreasing,
});
});
});
})();
});
26 changes: 26 additions & 0 deletions tests/parser/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,32 @@ describe("MetarParser", () => {
expect((metar.runwaysInfo[0] as IRunwayInfoRange).trend).toBe("N");
});

test("parses canadian station", () => {
const input =
"CYWG 172000Z 30015G25KT 3/4SM R36/4000FT/D -SN BLSN BKN008 OVC040 M05/M08 A2992 REFZRA WS RWY36 RMK SF5NS3 SLP134";

const metar = new MetarParser(en).parse(input);

expect(metar.station).toBe("CYWG");
expect(metar.day).toBe(17);
expect(metar.hour).toBe(20);
expect(metar.minute).toBe(0);
expect(metar.wind).toBeDefined();
expect(metar.wind?.speed).toBe(15);
expect(metar.wind?.gust).toBe(25);
expect(metar.wind?.direction).toBe("WNW");
expect(metar.wind?.unit).toBe("KT");
expect(metar.visibility).toBeDefined();
expect(metar.visibility).toEqual({
value: 0.75,
unit: DistanceUnit.StatuteMiles,
});
expect(metar.runwaysInfo).toHaveLength(1);
expect(metar.runwaysInfo[0].name).toBe("36");
expect((metar.runwaysInfo[0] as IRunwayInfoRange).minRange).toBe(4000);
expect((metar.runwaysInfo[0] as IRunwayInfoRange).trend).toBe("D");
});

test("parses 'AUTO' as station if no station identifier", () => {
const input = "AUTO 061950Z 10002KT 9999NDV NCD 01/M00 Q1015 RMK=";

Expand Down

0 comments on commit 256c37a

Please sign in to comment.