diff --git a/src/locales/en/constants.ts b/src/locales/en/constants.ts index 298b04ab..ae63c795 100644 --- a/src/locales/en/constants.ts +++ b/src/locales/en/constants.ts @@ -277,7 +277,7 @@ export const TIME_UNITS_NO_ABBR_PATTERN = repeatedTimeunitPattern( TIME_UNIT_CONNECTOR_PATTERN ); -export function parseTimeUnits(timeunitText): TimeUnits { +export function parseTimeUnits(timeunitText): null | TimeUnits { const fragments = {}; let remainingText = timeunitText; let match = SINGLE_TIME_UNIT_REGEX.exec(remainingText); @@ -286,10 +286,16 @@ export function parseTimeUnits(timeunitText): TimeUnits { remainingText = remainingText.substring(match[0].length).trim(); match = SINGLE_TIME_UNIT_REGEX.exec(remainingText); } + if (Object.keys(fragments).length == 0) { + return null; + } return fragments; } function collectDateTimeFragment(fragments, match) { + if (match[0].match(/^[a-zA-Z]+$/)) { + return; + } const num = parseNumberPattern(match[1]); const unit = TIME_UNIT_DICTIONARY[match[2].toLowerCase()]; fragments[unit] = num; diff --git a/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts b/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts index a00d40cc..6f786f93 100644 --- a/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts +++ b/src/locales/en/parsers/ENTimeUnitAgoFormatParser.ts @@ -18,8 +18,10 @@ export default class ENTimeUnitAgoFormatParser extends AbstractParserWithWordBou innerExtract(context: ParsingContext, match: RegExpMatchArray) { const timeUnits = parseTimeUnits(match[1]); + if (!timeUnits) { + return null; + } const outputTimeUnits = reverseTimeUnits(timeUnits); - return ParsingComponents.createRelativeFromReference(context.reference, outputTimeUnits); } } diff --git a/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts b/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts index 505e2596..f76c0c66 100644 --- a/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts +++ b/src/locales/en/parsers/ENTimeUnitCasualRelativeFormatParser.ts @@ -19,9 +19,12 @@ export default class ENTimeUnitCasualRelativeFormatParser extends AbstractParser return this.allowAbbreviations ? PATTERN : PATTERN_NO_ABBR; } - innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents { + innerExtract(context: ParsingContext, match: RegExpMatchArray) { const prefix = match[1].toLowerCase(); let timeUnits = parseTimeUnits(match[2]); + if (!timeUnits) { + return null; + } switch (prefix) { case "last": case "past": @@ -29,7 +32,6 @@ export default class ENTimeUnitCasualRelativeFormatParser extends AbstractParser timeUnits = reverseTimeUnits(timeUnits); break; } - return ParsingComponents.createRelativeFromReference(context.reference, timeUnits); } } diff --git a/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts b/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts index 91286951..7aff05a2 100644 --- a/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts +++ b/src/locales/en/parsers/ENTimeUnitLaterFormatParser.ts @@ -21,7 +21,10 @@ export default class ENTimeUnitLaterFormatParser extends AbstractParserWithWordB } innerExtract(context: ParsingContext, match: RegExpMatchArray) { - const fragments = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]); - return ParsingComponents.createRelativeFromReference(context.reference, fragments); + const timeUnits = parseTimeUnits(match[GROUP_NUM_TIMEUNITS]); + if (!timeUnits) { + return null; + } + return ParsingComponents.createRelativeFromReference(context.reference, timeUnits); } } diff --git a/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts b/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts index 1ffea93b..1591aee4 100644 --- a/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts +++ b/src/locales/en/parsers/ENTimeUnitWithinFormatParser.ts @@ -33,13 +33,15 @@ export default class ENTimeUnitWithinFormatParser extends AbstractParserWithWord return context.option.forwardDate ? PATTERN_WITH_OPTIONAL_PREFIX : PATTERN_WITH_PREFIX; } - innerExtract(context: ParsingContext, match: RegExpMatchArray): ParsingComponents { + innerExtract(context: ParsingContext, match: RegExpMatchArray) { // Exclude "for the unit" phases, e.g. "for the year" if (match[0].match(/^for\s*the\s*\w+/)) { return null; } - const timeUnits = parseTimeUnits(match[1]); + if (!timeUnits) { + return null; + } return ParsingComponents.createRelativeFromReference(context.reference, timeUnits); } } diff --git a/test/en/en_time_units_ago.test.ts b/test/en/en_time_units_ago.test.ts index 096900f6..58fae5cf 100644 --- a/test/en/en_time_units_ago.test.ts +++ b/test/en/en_time_units_ago.test.ts @@ -347,4 +347,7 @@ test("Test - Negative cases", function () { testUnexpectedResult(chrono, "15 hours 29 min"); testUnexpectedResult(chrono, "a few hour"); testUnexpectedResult(chrono, "5 days"); + + testUnexpectedResult(chrono, "am ago"); + testUnexpectedResult(chrono, "them ago"); }); diff --git a/test/en/en_time_units_casual_relative.test.ts b/test/en/en_time_units_casual_relative.test.ts index 59107743..b9e2a6e6 100644 --- a/test/en/en_time_units_casual_relative.test.ts +++ b/test/en/en_time_units_casual_relative.test.ts @@ -164,4 +164,7 @@ test("Test - Negative cases", () => { testUnexpectedResult(chrono.casual, "1 m", new Date(2015, 7 - 1, 10, 12, 14)); testUnexpectedResult(chrono.casual, "the day", new Date(2015, 7 - 1, 10, 12, 14)); testUnexpectedResult(chrono.casual, "a day", new Date(2015, 7 - 1, 10, 12, 14)); + + testUnexpectedResult(chrono, "+am"); + testUnexpectedResult(chrono, "+them"); }); diff --git a/test/en/en_time_units_later.test.ts b/test/en/en_time_units_later.test.ts index 31e4cf1a..fbb1a0f7 100644 --- a/test/en/en_time_units_later.test.ts +++ b/test/en/en_time_units_later.test.ts @@ -354,3 +354,7 @@ test("Test - Plus after reference", () => { expect(result.start.get("minute")).toBe(10); }); }); + +test("Test - Negative cases", () => { + testUnexpectedResult(chrono, "tell them later"); +}); diff --git a/test/en/en_time_units_within.test.ts b/test/en/en_time_units_within.test.ts index d610b59f..703d9cfa 100644 --- a/test/en/en_time_units_within.test.ts +++ b/test/en/en_time_units_within.test.ts @@ -408,3 +408,8 @@ test("Test - Forward date option", () => { expect(result.start.get("day")).toBe(1); }); }); + +test("Test - Negative cases", () => { + testUnexpectedResult(chrono, "in am"); + testUnexpectedResult(chrono, "in them"); +});