Skip to content

Commit

Permalink
Fix test for LW
Browse files Browse the repository at this point in the history
Forgot to pass allowWeekday to hasValidDays
  • Loading branch information
Kniggebrot committed Jul 26, 2023
1 parent cfc3e8e commit a5991c7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
6 changes: 6 additions & 0 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,12 @@ describe('validate', () => {
const validDOM = isValidCron('* * L * *', {allowLast: true})
expect(validDOM).toBeTruthy()

const validLW = isValidCron('* * LW * *', {allowLast: true, allowWeekday: true})
expect(validLW).toBeTruthy()

const validLWDOW = isValidCron('* * * * LW', {allowLast: true, allowWeekday: true})
expect(validLWDOW).toBeFalsy()

const validDOMAlias = isValidCron('* * L * WED', {allowLast: true, alias:true})
expect(validDOMAlias).toBeTruthy()

Expand Down
43 changes: 29 additions & 14 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,30 @@ const isValidHashed = (value: string[], start: number, stop: number): boolean =>
}
}

const isValidRange = (value: string, start: number, stop: number, allowHashed?: boolean): boolean => {
const isValidLast = (value: string[], start: number, stop: number, allowWeekday: boolean, inWeekday: boolean): boolean => {
switch (value.length) {
case 1:
// Only L or LW for DOM, xL for DOW
return value[0] === "L" || (!inWeekday && allowWeekday && value[0] === "LW") || ( inWeekday && value[0].slice(-1) === "L" && isInRange(safeParseInt(value[0].slice(0,-1)), start, stop) )
case 2:
// L with offset
return value[0] === "L" && isInRange( safeParseInt(value[1]), start, stop )
default:
return false
}
}

const isValidRange = (value: string, start: number, stop: number, allowHashed?: boolean, allowLast?: boolean, allowWeekday?: boolean, inWeekday?: boolean): boolean => {
const sides = value.split('-')
if (allowHashed && sides[0].slice(0,1) === "H") {
return isValidHashed(sides, start, stop)
}
switch (sides.length) {
case 1:
return isWildcard(value) || isInRange(safeParseInt(value), start, stop)
return isWildcard(value) || isInRange(safeParseInt(value), start, stop) || (!!allowLast && isValidLast(sides, start, stop, !!allowWeekday, !!inWeekday))
case 2:
const [small, big] = sides.map((side: string): number => safeParseInt(side))
return small <= big && isInRange(small, start, stop) && isInRange(big, start, stop)
return (small <= big && isInRange(small, start, stop) && isInRange(big, start, stop)) || (!!allowLast && isValidLast(sides, start, stop, !!allowWeekday, !!inWeekday))
default:
return false
}
Expand All @@ -54,8 +67,8 @@ const isValidStep = (value: string | undefined): boolean => {
return value === undefined || (value.search(/[^\d]/) === -1 && safeParseInt(value) > 0)
}

const validateForRange = (value: string, start: number, stop: number, allowHashed?: boolean): boolean => {
if (value.search(/[^\d-,\/*H()]/) !== -1) {
const validateForRange = (value: string, start: number, stop: number, allowHashed?: boolean, allowLast?: boolean, allowWeekday?: boolean, inWeekday?: boolean): boolean => {
if (value.search(/[^\d-,\/*H()LW]/) !== -1) {
return false
}

Expand All @@ -74,7 +87,7 @@ const validateForRange = (value: string, start: number, stop: number, allowHashe

// If we don't have a `/`, right will be undefined which is considered a valid step if we don't a `/`.
const [left, right] = splits
return isValidRange(left, start, stop, allowHashed) && isValidStep(right)
return isValidRange(left, start, stop, allowHashed, allowLast, allowWeekday, inWeekday) && isValidStep(right)
})
}

Expand All @@ -90,8 +103,8 @@ const hasValidHours = (hours: string, allowHashed?: boolean): boolean => {
return validateForRange(hours, 0, 23, allowHashed)
}

const hasValidDays = (days: string, allowBlankDay?: boolean, allowHashed?: boolean): boolean => {
return (allowBlankDay && isQuestionMark(days)) || validateForRange(days, 1, 31, allowHashed)
const hasValidDays = (days: string, allowBlankDay?: boolean, allowHashed?: boolean, allowLast?: boolean, allowWeekday?: boolean): boolean => {
return (allowBlankDay && isQuestionMark(days)) || validateForRange(days, 1, 31, allowHashed, allowLast, allowWeekday)
}

const monthAlias: { [key: string]: string } = {
Expand Down Expand Up @@ -136,7 +149,7 @@ const weekdaysAlias: { [key: string]: string } = {
sat: '6'
}

const hasValidWeekdays = (weekdays: string, alias?: boolean, allowBlankDay?: boolean, allowSevenAsSunday?: boolean, allowHashed?: boolean): boolean => {
const hasValidWeekdays = (weekdays: string, alias?: boolean, allowBlankDay?: boolean, allowSevenAsSunday?: boolean, allowHashed?: boolean, allowLast?: boolean, allowWeekday?: boolean): boolean => {

// If there is a question mark, checks if the allowBlankDay flag is set
if (allowBlankDay && isQuestionMark(weekdays)) {
Expand All @@ -155,10 +168,10 @@ const hasValidWeekdays = (weekdays: string, alias?: boolean, allowBlankDay?: boo
return weekdaysAlias[match] === undefined ? match : weekdaysAlias[match]
})
// If any invalid alias was used, it won't pass the other checks as there will be non-numeric values in the weekdays
return validateForRange(remappedWeekdays, 0, allowSevenAsSunday ? 7 : 6, allowHashed)
return validateForRange(remappedWeekdays, 0, allowSevenAsSunday ? 7 : 6, allowHashed, allowLast, allowWeekday, true)
}

return validateForRange(weekdays, 0, allowSevenAsSunday ? 7 : 6, allowHashed)
return validateForRange(weekdays, 0, allowSevenAsSunday ? 7 : 6, allowHashed, allowLast, allowWeekday, true)
}

const hasCompatibleDayFormat = (days: string, weekdays: string, allowBlankDay?: boolean) => {
Expand All @@ -176,6 +189,7 @@ type Options = {
allowSevenAsSunday: boolean
allowHashed: boolean
allowLast: boolean
allowWeekday: boolean
}

const defaultOptions: Options = {
Expand All @@ -184,7 +198,8 @@ const defaultOptions: Options = {
allowBlankDay: false,
allowSevenAsSunday: false,
allowHashed: false,
allowLast: false
allowLast: false,
allowWeekday: false
}

export const isValidCron = (cron: string, options?: Partial<Options>): boolean => {
Expand All @@ -209,9 +224,9 @@ export const isValidCron = (cron: string, options?: Partial<Options>): boolean =
const [minutes, hours, days, months, weekdays] = splits
checks.push(hasValidMinutes(minutes, options.allowHashed))
checks.push(hasValidHours(hours, options.allowHashed))
checks.push(hasValidDays(days, options.allowBlankDay, options.allowHashed))
checks.push(hasValidDays(days, options.allowBlankDay, options.allowHashed, options.allowLast, options.allowWeekday))
checks.push(hasValidMonths(months, options.alias, options.allowHashed))
checks.push(hasValidWeekdays(weekdays, options.alias, options.allowBlankDay, options.allowSevenAsSunday, options.allowHashed))
checks.push(hasValidWeekdays(weekdays, options.alias, options.allowBlankDay, options.allowSevenAsSunday, options.allowHashed, options.allowLast))
checks.push(hasCompatibleDayFormat(days, weekdays, options.allowBlankDay))

return checks.every(Boolean)
Expand Down

0 comments on commit a5991c7

Please sign in to comment.