From 43ddfecb5be16ecd64ee2f338fd01c18f9a48267 Mon Sep 17 00:00:00 2001 From: Anya Wallace Date: Mon, 16 Dec 2024 17:11:03 -0800 Subject: [PATCH] fix duration regex and add unit tests --- .../AnnotationFormatter/duration-formatter.ts | 18 ++++++++------- .../test/formatters.test.ts | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/packages/core/entity/AnnotationFormatter/duration-formatter.ts b/packages/core/entity/AnnotationFormatter/duration-formatter.ts index a0d5ea990..ae479dd9a 100644 --- a/packages/core/entity/AnnotationFormatter/duration-formatter.ts +++ b/packages/core/entity/AnnotationFormatter/duration-formatter.ts @@ -26,14 +26,16 @@ export default { }, valueOf(value: any) { - const RANGE_OPERATOR_REGEX = /([0-9]+)D ([0-9]+)H ([0-9]+)M ([0-9]*\.?[0-9]+)S/g; - const exec = RANGE_OPERATOR_REGEX.exec(value); - // Check if value is a pre-formatted duration string - if (exec) { - const daysInMs = Number(exec[1]) * msInADay; - const hrsInMs = Number(exec[2]) * msInAnHour; - const minsInMs = Number(exec[3]) * msInAMinute; - const secsInMs = Number(exec[4]) * msInASecond; + // Check for pre-formatted duration strings: must have at least one of #D, #H, #M, or #S in that order + const regexMatch = value.match( + /^(([0-9]+)D)?\s?(([0-9]+)H)?\s?(([0-9]+)M)?\s?(([0-9]*\.?[0-9]+)S)?$/ + ); + if (regexMatch) { + // Capture group order is [full string, aD, a, bH, b, cM, c, dS, d] + const daysInMs = (Number(regexMatch[2]) || 0) * msInADay; + const hrsInMs = (Number(regexMatch[4]) || 0) * msInAnHour; + const minsInMs = (Number(regexMatch[6]) || 0) * msInAMinute; + const secsInMs = (Number(regexMatch[8]) || 0) * msInASecond; return daysInMs + hrsInMs + minsInMs + secsInMs; } return Number(value); diff --git a/packages/core/entity/AnnotationFormatter/test/formatters.test.ts b/packages/core/entity/AnnotationFormatter/test/formatters.test.ts index 3753df368..757a177c9 100644 --- a/packages/core/entity/AnnotationFormatter/test/formatters.test.ts +++ b/packages/core/entity/AnnotationFormatter/test/formatters.test.ts @@ -143,5 +143,27 @@ describe("Annotation formatters", () => { it("formats a duration with less than a second", () => { expect(durationFormatter.displayValue(125)).to.equal("0.125S"); }); + + it("extracts time in milliseconds from formatted duration strings", () => { + expect(durationFormatter.valueOf("1D 23H 45M 6.78S")).to.equal(171906780); + }); + + it("extracts time in milliseconds from formatted strings with only days", () => { + expect(durationFormatter.valueOf("100D")).to.equal(8.64e9); + }); + + it("extracts time in milliseconds from formatted strings with only some units", () => { + expect(durationFormatter.valueOf("12H 34S")).to.equal(43234000); + }); + + it("extracts time in milliseconds from non-formatted numerical-valued strings", () => { + expect(durationFormatter.valueOf("9876")).to.equal(9876); + }); + + it("returns NaN when string letters or order don't match duration pattern", () => { + expect(isNaN(durationFormatter.valueOf("4A"))).to.be.true; + expect(isNaN(durationFormatter.valueOf("4D 3M 2H 12S"))).to.be.true; + expect(isNaN(durationFormatter.valueOf("DHMS"))).to.be.true; + }); }); });