From d55bbf45478e24485435ad9edb0405c690313146 Mon Sep 17 00:00:00 2001 From: Jere Date: Fri, 26 Jun 2026 17:02:31 +0300 Subject: [PATCH] Fix !timer date parsing: strict mode, flexible formats, time-before-date - Accept time-before-date input (e.g. "14:45 12.3.2077") which previously silently set a wrong time due to lenient moment.js parsing - Parse only the first 1-2 tokens as date/time so an optional message after the date no longer breaks parsing in strict mode - Add single-digit day/month variants (D.M) alongside zero-padded (DD.MM) - Add reversed time-first formats (HH:mm DD.MM, HH:mm DD.MM.YYYY) - Add CI tests covering duration (5m, 2h), time-only, time-first date, date-first, and invalid input Fixes #20 --- features/timer.js | 22 ++++++++++++++++------ test/cases.json | 9 ++++++++- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/features/timer.js b/features/timer.js index 17c07d7..34b1c88 100644 --- a/features/timer.js +++ b/features/timer.js @@ -3,8 +3,16 @@ const _ = require('underscore'), TimerDB = require('../lib/timerdb').TimerDB; var timerdb = new TimerDB(), - date_strs = ['HH:mm', 'DD.MM', 'DD.MM HH:mm', 'DD.MM.YYYY', 'DD.MM.YYYY HH:mm'], - help_str = "Supported formats: [number]s/m/h, " + date_strs.join(", "); + date_strs = [ + 'HH:mm', + 'D.M', 'DD.MM', + 'D.M HH:mm', 'DD.MM HH:mm', + 'HH:mm D.M', 'HH:mm DD.MM', + 'D.M.YYYY', 'DD.MM.YYYY', + 'D.M.YYYY HH:mm', 'DD.MM.YYYY HH:mm', + 'HH:mm D.M.YYYY', 'HH:mm DD.MM.YYYY', + ], + help_str = "Supported formats: [number]s/m/h, HH:mm, DD.MM, DD.MM HH:mm, HH:mm DD.MM, DD.MM.YYYY, DD.MM.YYYY HH:mm, HH:mm DD.MM.YYYY"; var timer = function(client, channel, from, line) { var say = function(msg) { @@ -23,14 +31,16 @@ var timer = function(client, channel, from, line) { var moment_delay = moment().add( initial(first_arg), last(first_arg)); - var moment_date = moment(_.rest(line_arr).join(" "), date_strs); + var date_two = line_arr.length >= 3 ? moment(first_arg + ' ' + line_arr[2], date_strs, true) : null; + var date_one = moment(first_arg, date_strs, true); if (first_arg.match(/^[0-9]{1,3}[a-zM]$/) && moment_delay.isValid()) { date = moment_delay; - } else if (first_arg.match(/(:|\.)/) && - moment_date.isValid()) { - date = moment_date; + } else if (date_two && date_two.isValid()) { + date = date_two; + } else if (date_one.isValid()) { + date = date_one; } else { say(help_str); return; diff --git a/test/cases.json b/test/cases.json index 571faf5..66fd289 100644 --- a/test/cases.json +++ b/test/cases.json @@ -24,5 +24,12 @@ { "cmd": "!add ciexpl this is a ci expl", "expect": "ciexpl", "desc": "pythonsimo expl add" }, { "cmd": "!expl ciexpl", "expect": "ci expl", "desc": "pythonsimo expl lookup" }, - { "cmd": "!remove ciexpl 1", "expect": "Deleted", "desc": "pythonsimo expl remove" } + { "cmd": "!remove ciexpl 1", "expect": "Deleted", "desc": "pythonsimo expl remove" }, + + { "cmd": "!timer 5m ci reminder", "expect": "Timer set to:.*202", "desc": "timer: duration in minutes" }, + { "cmd": "!timer 2h ci reminder", "expect": "Timer set to:.*202", "desc": "timer: duration in hours" }, + { "cmd": "!timer 23:59 ci reminder", "expect": "23:59", "desc": "timer: time-only with message" }, + { "cmd": "!timer 14:45 1.1.2077 ci reminder", "expect": "Jan 01 2077 14:45", "desc": "timer: time-first date format with message" }, + { "cmd": "!timer 1.1.2077 14:45 ci reminder", "expect": "Jan 01 2077 14:45", "desc": "timer: date-first format with message" }, + { "cmd": "!timer garbage", "expect": "Supported formats", "desc": "timer: invalid input shows help" } ]