From f7b8d1ac072c7dd6682656c5235cf967f16003bb Mon Sep 17 00:00:00 2001 From: Valentin Valls Date: Wed, 24 Aug 2022 23:13:35 +0200 Subject: [PATCH 1/3] Create a more consistent 'parseDuration' - Remove 'durationToDate' which was not a usable function --- src/diagrams/gantt/ganttDb.js | 15 +++++++++++---- src/diagrams/gantt/ganttDb.spec.js | 10 +++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js index b69d46518..e8c75a982 100644 --- a/src/diagrams/gantt/ganttDb.js +++ b/src/diagrams/gantt/ganttDb.js @@ -230,7 +230,15 @@ const getStartDate = function (prevTime, dateFormat, str) { return new Date(); }; -const durationToDate = function (durationStatement, relativeTime) { +/** + * Parse a duration as an absolute date. + * + * @param durationStr A string representing a duration + * @param relativeTime The moment when this duration starts + * @returns The date of the end of the duration. + */ +const parseDuration = function (durationStr, relativeTime) { + const durationStatement = /^([\d]+)([wdhms]|ms)$/.exec(durationStr.trim()); if (durationStatement !== null) { switch (durationStatement[2]) { case 'ms': @@ -253,7 +261,6 @@ const durationToDate = function (durationStatement, relativeTime) { break; } } - // Default date - now return relativeTime.toDate(); }; @@ -270,7 +277,7 @@ const getEndDate = function (prevTime, dateFormat, str, inclusive) { return mDate.toDate(); } - return durationToDate(/^([\d]+)([wdhms]|ms)$/.exec(str.trim()), moment(prevTime)); + return parseDuration(str, moment(prevTime)); }; let taskCnt = 0; @@ -666,7 +673,7 @@ export default { setLink, getLinks, bindFunctions, - durationToDate, + parseDuration, isInvalidDate, }; diff --git a/src/diagrams/gantt/ganttDb.spec.js b/src/diagrams/gantt/ganttDb.spec.js index d07aee4bf..1d2b3724f 100644 --- a/src/diagrams/gantt/ganttDb.spec.js +++ b/src/diagrams/gantt/ganttDb.spec.js @@ -8,11 +8,11 @@ describe('when using the ganttDb', function () { describe('when using relative times', function () { it.each` - diff | date | expected - ${' 1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()} - ${' 1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()} + diff | date | expected + ${'1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()} + ${'1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()} `('should add $diff to $date resulting in $expected', ({ diff, date, expected }) => { - expect(ganttDb.durationToDate(diff, date)).toEqual(expected); + expect(ganttDb.parseDuration(diff, date)).toEqual(expected); }); }); @@ -106,7 +106,7 @@ describe('when using the ganttDb', function () { ganttDb.addTask('test2', 'id2,after id1,5ms'); ganttDb.addSection('testa2'); ganttDb.addTask('test3', 'id3,20,10ms'); - ganttDb.addTask('test4', 'id4,after id3,5ms'); + ganttDb.addTask('test4', 'id4,after id3,0.005s'); const tasks = ganttDb.getTasks(); From 3315ae838263ff767fd731cede947bfaca536d2d Mon Sep 17 00:00:00 2001 From: Valentin Valls Date: Wed, 24 Aug 2022 23:50:42 +0200 Subject: [PATCH 2/3] Supports duration in decimal --- cypress/integration/rendering/gantt.spec.js | 2 +- src/diagrams/gantt/ganttDb.js | 2 +- src/diagrams/gantt/ganttDb.spec.js | 10 ++++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cypress/integration/rendering/gantt.spec.js b/cypress/integration/rendering/gantt.spec.js index 7dc7c6cf5..e6c79a717 100644 --- a/cypress/integration/rendering/gantt.spec.js +++ b/cypress/integration/rendering/gantt.spec.js @@ -175,7 +175,7 @@ describe('Gantt diagram', () => { Another task :after a1, 20ms section Another Another another task :b1, 20, 12ms - Another another another task :after b1, 24ms + Another another another task :after b1, 0.024s `, {} ); diff --git a/src/diagrams/gantt/ganttDb.js b/src/diagrams/gantt/ganttDb.js index e8c75a982..996f22e79 100644 --- a/src/diagrams/gantt/ganttDb.js +++ b/src/diagrams/gantt/ganttDb.js @@ -238,7 +238,7 @@ const getStartDate = function (prevTime, dateFormat, str) { * @returns The date of the end of the duration. */ const parseDuration = function (durationStr, relativeTime) { - const durationStatement = /^([\d]+)([wdhms]|ms)$/.exec(durationStr.trim()); + const durationStatement = /^(\d+(?:\.\d+)?)([wdhms]|ms)$/.exec(durationStr.trim()); if (durationStatement !== null) { switch (durationStatement[2]) { case 'ms': diff --git a/src/diagrams/gantt/ganttDb.spec.js b/src/diagrams/gantt/ganttDb.spec.js index 1d2b3724f..e3622a5fb 100644 --- a/src/diagrams/gantt/ganttDb.spec.js +++ b/src/diagrams/gantt/ganttDb.spec.js @@ -8,11 +8,13 @@ describe('when using the ganttDb', function () { describe('when using relative times', function () { it.each` - diff | date | expected - ${'1d'} | ${moment('2019-01-01')} | ${moment('2019-01-02').toDate()} - ${'1w'} | ${moment('2019-01-01')} | ${moment('2019-01-08').toDate()} + 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)).toEqual(expected); + expect(ganttDb.parseDuration(diff, date).toISOString()).toEqual(expected); }); }); From ba4f7d2ceba80f386e39d8da2fb9871d4a749ea4 Mon Sep 17 00:00:00 2001 From: Valentin Valls Date: Thu, 25 Aug 2022 23:15:16 +0200 Subject: [PATCH 3/3] 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); }); });