From ca451fd2d6a6a7ca1b4fc8d09efff6c6d0c46fea Mon Sep 17 00:00:00 2001 From: Rene Saarsoo Date: Mon, 21 Sep 2020 17:06:51 +0300 Subject: [PATCH] Enforce strict format for interval durations --- src/parser/parser.test.ts | 37 +++++++++++++++++++++++++++++++++++++ src/parser/tokenizer.ts | 4 ++-- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/parser/parser.test.ts b/src/parser/parser.test.ts index bba3e68..93e70c9 100644 --- a/src/parser/parser.test.ts +++ b/src/parser/parser.test.ts @@ -121,4 +121,41 @@ Cooldown: 5:30 70%..45% ] `); }); + + const parseInterval = (interval: string) => + parse(`Name: My Workout\n${interval}`).intervals[0]; + + it("parses correct duration formats", () => { + expect(parseInterval("Interval: 0:10 50%").duration).toEqual(10); + expect(parseInterval("Interval: 00:10 50%").duration).toEqual(10); + expect(parseInterval("Interval: 0:00:10 50%").duration).toEqual(10); + expect(parseInterval("Interval: 0:02:05 50%").duration).toEqual(125); + expect(parseInterval("Interval: 1:00:00 50%").duration).toEqual(3600); + expect(parseInterval("Interval: 1:00:0 50%").duration).toEqual(3600); + expect(parseInterval("Interval: 1:0:0 50%").duration).toEqual(3600); + expect(parseInterval("Interval: 10:00:00 50%").duration).toEqual(36000); + }); + + it("throws error for incorrect duration formats", () => { + expect(() => + parseInterval("Interval: 10 50%") + ).toThrowErrorMatchingInlineSnapshot( + `"Unrecognized interval parameter \\"10\\""` + ); + expect(() => + parseInterval("Interval: :10 50%") + ).toThrowErrorMatchingInlineSnapshot( + `"Unrecognized interval parameter \\":10\\""` + ); + expect(() => + parseInterval("Interval: 0:100 50%") + ).toThrowErrorMatchingInlineSnapshot( + `"Unrecognized interval parameter \\"0:100\\""` + ); + expect(() => + parseInterval("Interval: 00:00:00:10 50%") + ).toThrowErrorMatchingInlineSnapshot( + `"Unrecognized interval parameter \\"00:00:00:10\\""` + ); + }); }); diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index d09828d..b87ec0e 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -50,7 +50,7 @@ const toSeconds = (str: string): number => { const toFraction = (percentage: number): number => percentage / 100; const tokenizeValueParam = (text: string): Token => { - if (/^[0-9:]+$/.test(text)) { + if (/^([0-9]{1,2}:)?[0-9]{1,2}:[0-9]{1,2}$/.test(text)) { return { type: "duration", value: toSeconds(text) }; } if (/^[0-9]+rpm$/.test(text)) { @@ -63,7 +63,7 @@ const tokenizeValueParam = (text: string): Token => { if (/^[0-9]+%$/.test(text)) { return { type: "intensity", value: toFraction(toInteger(text)) }; } - throw new Error(`Unrecognized parameter "${text}"`); + throw new Error(`Unrecognized interval parameter "${text}"`); }; const tokenizeParams = (type: LabelTokenValue, text: string): Token[] => {