From ba4f7d2ceba80f386e39d8da2fb9871d4a749ea4 Mon Sep 17 00:00:00 2001 From: Valentin Valls Date: Thu, 25 Aug 2022 23:15:16 +0200 Subject: [PATCH] Rework 'parseDuration' as a pure duration parsing --- src/diagrams/gantt/ganttDb.js | 56 ++++++++++++++---------------- src/diagrams/gantt/ganttDb.spec.js | 17 ++++----- 2 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js index 996f22e79..f6a526759 100644 --- a/src/diagrams/gantt/ganttDb.js +++ b/src/diagrams/gantt/ganttDb.js @@ -231,37 +231,30 @@ const getStartDate = function (prevTime, dateFormat, str) { }; /** - * Parse a duration as an absolute date. + * Parse a string as a moment duration. * - * @param durationStr A string representing a duration - * @param relativeTime The moment when this duration starts - * @returns The date of the end of the duration. + * The string have to be compound by a value and a shorthand duration unit. For example `5d` + * representes 5 days. + * + * Shorthand unit supported are: + * + * - `y` for years + * - `M` for months + * - `w` for weeks + * - `d` for days + * - `h` for hours + * - `s` for seconds + * - `ms` for milliseconds + * + * @param {string} str - A string representing the duration. + * @returns {moment.Duration} A moment duration, including an invalid moment for invalid input string. */ -const parseDuration = function (durationStr, relativeTime) { - const durationStatement = /^(\d+(?:\.\d+)?)([wdhms]|ms)$/.exec(durationStr.trim()); - if (durationStatement !== null) { - switch (durationStatement[2]) { - case 'ms': - relativeTime.add(durationStatement[1], 'milliseconds'); - break; - case 's': - relativeTime.add(durationStatement[1], 'seconds'); - break; - case 'm': - relativeTime.add(durationStatement[1], 'minutes'); - break; - case 'h': - relativeTime.add(durationStatement[1], 'hours'); - break; - case 'd': - relativeTime.add(durationStatement[1], 'days'); - break; - case 'w': - relativeTime.add(durationStatement[1], 'weeks'); - break; - } +const parseDuration = function (str) { + const statement = /^(\d+(?:\.\d+)?)([yMwdhms]|ms)$/.exec(str.trim()); + if (statement !== null) { + return moment.duration(Number.parseFloat(statement[1]), statement[2]); } - return relativeTime.toDate(); + return moment.duration.invalid(); }; const getEndDate = function (prevTime, dateFormat, str, inclusive) { @@ -277,7 +270,12 @@ const getEndDate = function (prevTime, dateFormat, str, inclusive) { return mDate.toDate(); } - return parseDuration(str, moment(prevTime)); + const endTime = moment(prevTime); + const duration = parseDuration(str); + if (duration.isValid()) { + endTime.add(duration); + } + return endTime.toDate(); }; let taskCnt = 0; diff --git a/src/diagrams/gantt/ganttDb.spec.js b/src/diagrams/gantt/ganttDb.spec.js index e3622a5fb..4d1c3860b 100644 --- a/src/diagrams/gantt/ganttDb.spec.js +++ b/src/diagrams/gantt/ganttDb.spec.js @@ -6,15 +6,16 @@ describe('when using the ganttDb', function () { ganttDb.clear(); }); - describe('when using relative times', function () { + describe('when using duration', function () { it.each` - diff | date | expected - ${'1d'} | ${moment.utc('2019-01-01')} | ${'2019-01-02T00:00:00.000Z'} - ${'1w'} | ${moment.utc('2019-01-01')} | ${'2019-01-08T00:00:00.000Z'} - ${'1ms'} | ${moment.utc('2019-01-01')} | ${'2019-01-01T00:00:00.001Z'} - ${'0.1s'} | ${moment.utc('2019-01-01')} | ${'2019-01-01T00:00:00.100Z'} - `('should add $diff to $date resulting in $expected', ({ diff, date, expected }) => { - expect(ganttDb.parseDuration(diff, date).toISOString()).toEqual(expected); + str | expected + ${'1d'} | ${moment.duration(1, 'd')} + ${'2w'} | ${moment.duration(2, 'w')} + ${'1ms'} | ${moment.duration(1, 'ms')} + ${'0.1s'} | ${moment.duration(100, 'ms')} + ${'1f'} | ${moment.duration.invalid()} + `('should $str resulting in $expected duration', ({ str, expected }) => { + expect(ganttDb.parseDuration(str)).toEqual(expected); }); });