From 066ccc5e155c208b5bf0a0accd2741158288d291 Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Fri, 20 Feb 2026 23:32:48 -0500 Subject: [PATCH 1/5] chore: update biome config --- biome.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/biome.json b/biome.json index 5e140cc6..8b4ade4f 100644 --- a/biome.json +++ b/biome.json @@ -12,7 +12,8 @@ "formatter": { "enabled": true, "indentStyle": "space", - "indentWidth": 2 + "indentWidth": 2, + "lineWidth": 120 }, "linter": { "enabled": true, From 1decb03cd3b916172456282c1339f0fab17e541d Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Fri, 20 Feb 2026 23:38:25 -0500 Subject: [PATCH 2/5] chore: restructure --- src/cache.ts | 24 +- src/callbackiterresult.ts | 29 - src/{dateutil.ts => date.ts} | 79 +- src/datetime.ts | 53 +- src/datewithzone.ts | 39 - src/helpers.ts | 20 +- src/index.ts | 10 +- src/iter/index.ts | 70 +- src/iter/poslist.ts | 4 +- src/{iterset.ts => iter/set.ts} | 11 +- src/iterinfo/index.ts | 41 +- src/iterinfo/yearinfo.ts | 3 +- src/iterresult.ts | 32 +- src/masks.ts | 12 +- src/nlp/i18n.ts | 10 +- src/nlp/index.ts | 24 +- src/nlp/parsetext.ts | 35 +- src/nlp/totext.ts | 149 +- src/{parseoptions.ts => parse/options.ts} | 58 +- src/{ => parse}/rrulestr.ts | 45 +- src/{parsestring.ts => parse/string.ts} | 12 +- .../stringify.ts} | 15 +- src/rrule.ts | 24 +- src/rrulebase.ts | 22 +- src/rruleset.ts | 29 +- src/types.ts | 12 +- src/weekday.ts | 10 +- test/{dateutil.test.ts => date.test.ts} | 2 +- test/datewithzone.test.ts | 12 +- test/helpers.test.ts | 12 +- test/lib/utils.ts | 46 +- test/nlp.test.ts | 28 +- test/optionstostring.test.ts | 7 +- test/parseoptions.test.ts | 2 +- test/parsestring.test.ts | 12 +- test/rrule.test.ts | 1379 +++-------------- test/rruleset.test.ts | 200 +-- test/rrulestr.test.ts | 159 +- 38 files changed, 591 insertions(+), 2140 deletions(-) delete mode 100644 src/callbackiterresult.ts rename src/{dateutil.ts => date.ts} (75%) delete mode 100644 src/datewithzone.ts rename src/{iterset.ts => iter/set.ts} (87%) rename src/{parseoptions.ts => parse/options.ts} (77%) rename src/{ => parse}/rrulestr.ts (84%) rename src/{parsestring.ts => parse/string.ts} (94%) rename src/{optionstostring.ts => parse/stringify.ts} (86%) rename test/{dateutil.test.ts => date.test.ts} (77%) diff --git a/src/cache.ts b/src/cache.ts index 966d5663..2e651fde 100644 --- a/src/cache.ts +++ b/src/cache.ts @@ -1,4 +1,4 @@ -import { clone, cloneDates } from './dateutil'; +import { clone, cloneDates } from './date'; import { isArray } from './helpers'; import IterResult, { type IterArgs } from './iterresult'; @@ -7,10 +7,7 @@ export type CacheKeys = 'before' | 'after' | 'between'; /** Max cached entries per query method (before/after/between) */ const MAX_CACHE_SIZE = 64; -function argsMatch( - left: IterArgs[keyof IterArgs] | undefined, - right: IterArgs[keyof IterArgs] | undefined, -) { +function argsMatch(left: IterArgs[keyof IterArgs] | undefined, right: IterArgs[keyof IterArgs] | undefined) { if (Array.isArray(left)) { if (!Array.isArray(right)) return false; if (left.length !== right.length) return false; @@ -35,11 +32,7 @@ export class Cache { * @param {Array,Date} value - an array of dates, one date, or null * @param {Object?} args - _iter arguments */ - public _cacheAdd( - what: CacheKeys | 'all', - value: Date[] | Date | null, - args?: Partial, - ) { + public _cacheAdd(what: CacheKeys | 'all', value: Date[] | Date | null, args?: Partial) { if (value) { value = value instanceof Date ? clone(value) : cloneDates(value); } @@ -63,10 +56,7 @@ export class Cache { * @return [] - cached, but zero occurrences (all/between) * @return [Date1, DateN] - cached (all/between) */ - public _cacheGet( - what: CacheKeys | 'all', - args?: Partial, - ): Date | Date[] | false | null { + public _cacheGet(what: CacheKeys | 'all', args?: Partial): Date | Date[] | false | null { let cached: Date | Date[] | false | null = false; const argsKeys = args ? (Object.keys(args) as (keyof IterArgs)[]) : []; const findCacheDiff = (item: IterArgs) => { @@ -102,10 +92,6 @@ export class Cache { this._cacheAdd(what, cached, args); } - return isArray(cached) - ? cloneDates(cached) - : cached instanceof Date - ? clone(cached) - : cached; + return isArray(cached) ? cloneDates(cached) : cached instanceof Date ? clone(cached) : cached; } } diff --git a/src/callbackiterresult.ts b/src/callbackiterresult.ts deleted file mode 100644 index 16078272..00000000 --- a/src/callbackiterresult.ts +++ /dev/null @@ -1,29 +0,0 @@ -import IterResult, { type IterArgs } from './iterresult'; - -type Iterator = (d: Date, len: number) => boolean; - -/** - * IterResult subclass that calls a callback function on each add, - * and stops iterating when the callback returns false. - */ -export default class CallbackIterResult extends IterResult<'all' | 'between'> { - private iterator: Iterator; - - constructor( - method: 'all' | 'between', - args: Partial, - iterator: Iterator, - ) { - super(method, args); - - this.iterator = iterator; - } - - add(date: Date) { - if (this.iterator(date, this._result.length)) { - this._result.push(date); - return true; - } - return false; - } -} diff --git a/src/dateutil.ts b/src/date.ts similarity index 75% rename from src/dateutil.ts rename to src/date.ts index 810c6092..0fb482f2 100644 --- a/src/dateutil.ts +++ b/src/date.ts @@ -2,14 +2,8 @@ import type { Time } from './datetime'; type Datelike = Pick; -export const datetime = ( - y: number, - m: number, - d: number, - h = 0, - i = 0, - s = 0, -) => new Date(Date.UTC(y, m - 1, d, h, i, s)); +export const datetime = (y: number, m: number, d: number, h = 0, i = 0, s = 0) => + new Date(Date.UTC(y, m - 1, d, h, i, s)); /** * General date-related utilities. @@ -45,26 +39,11 @@ export const PY_WEEKDAYS = [6, 0, 1, 2, 3, 4, 5]; * py_date.timetuple()[7] */ export const getYearDay = (date: Date) => { - const dateNoTime = new Date( - date.getUTCFullYear(), - date.getUTCMonth(), - date.getUTCDate(), - ); - return ( - Math.ceil( - (dateNoTime.valueOf() - new Date(date.getUTCFullYear(), 0, 1).valueOf()) / - ONE_DAY, - ) + 1 - ); + const dateNoTime = new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()); + return Math.ceil((dateNoTime.valueOf() - new Date(date.getUTCFullYear(), 0, 1).valueOf()) / ONE_DAY) + 1; }; -export const isLeapYear = (year: number) => - (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; - -export const isDate = (value: unknown): value is Date => value instanceof Date; - -export const isValidDate = (value: unknown): value is Date => - isDate(value) && !Number.isNaN(value.getTime()); +export const isLeapYear = (year: number) => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; /** * @return {Number} the date's timezone offset in ms @@ -95,21 +74,17 @@ export const toOrdinal = (date: Date) => daysBetween(date, ORDINAL_BASE); /** * @see - */ -export const fromOrdinal = (ordinal: number) => - new Date(ORDINAL_BASE.getTime() + ordinal * ONE_DAY); +export const fromOrdinal = (ordinal: number) => new Date(ORDINAL_BASE.getTime() + ordinal * ONE_DAY); export const getMonthDays = (date: Date): number => { const month = date.getUTCMonth(); - return month === 1 && isLeapYear(date.getUTCFullYear()) - ? 29 - : MONTH_DAYS[month]!; + return month === 1 && isLeapYear(date.getUTCFullYear()) ? 29 : MONTH_DAYS[month]!; }; /** * @return {Number} python-like weekday */ -export const getWeekday = (date: Date): number => - PY_WEEKDAYS[date.getUTCDay()]!; +export const getWeekday = (date: Date): number => PY_WEEKDAYS[date.getUTCDay()]!; /** * @see: @@ -204,3 +179,41 @@ export const dateInTimeZone = (date: Date, timeZone: string) => { return new Date(date.getTime() - tzOffset); }; + +export class DateWithZone { + public date: Date; + public tzid?: string | null; + + constructor(date: Date, tzid?: string | null) { + if (Number.isNaN(date.getTime())) { + throw new RangeError('Invalid date passed to DateWithZone'); + } + this.date = date; + this.tzid = tzid; + } + + private get isUTC() { + return !this.tzid || this.tzid.toUpperCase() === 'UTC'; + } + + public toString() { + const datestr = timeToUntilString(this.date.getTime(), this.isUTC); + if (!this.isUTC) { + return `;TZID=${this.tzid}:${datestr}`; + } + + return `:${datestr}`; + } + + public getTime() { + return this.date.getTime(); + } + + public rezonedDate() { + if (this.isUTC) { + return this.date; + } + + return dateInTimeZone(this.date, this.tzid!); + } +} diff --git a/src/datetime.ts b/src/datetime.ts index 8f168128..66368aef 100644 --- a/src/datetime.ts +++ b/src/datetime.ts @@ -1,4 +1,4 @@ -import { getWeekday, MAXYEAR, monthRange } from './dateutil'; +import { getWeekday, MAXYEAR, monthRange } from './date'; import { divmod, empty, pymod } from './helpers'; import { Frequency, type ParsedOptions } from './types'; @@ -8,12 +8,7 @@ export class Time { public second: number; public millisecond: number; - constructor( - hour: number, - minute: number, - second: number, - millisecond: number, - ) { + constructor(hour: number, minute: number, second: number, millisecond: number) { this.hour = hour; this.minute = minute; this.second = second; @@ -37,10 +32,7 @@ export class Time { } getTime() { - return ( - (this.hour * 60 * 60 + this.minute * 60 + this.second) * 1000 + - this.millisecond - ); + return (this.hour * 60 * 60 + this.minute * 60 + this.second) * 1000 + this.millisecond; } } @@ -82,15 +74,7 @@ export class DateTime extends Time { getTime() { return new Date( - Date.UTC( - this.year, - this.month - 1, - this.day, - this.hour, - this.minute, - this.second, - this.millisecond, - ), + Date.UTC(this.year, this.month - 1, this.day, this.hour, this.minute, this.second, this.millisecond), ).getTime(); } @@ -156,16 +140,10 @@ export class DateTime extends Time { } } - public addMinutes( - minutes: number, - filtered: boolean, - byhour: number[], - byminute: number[], - ) { + public addMinutes(minutes: number, filtered: boolean, byhour: number[], byminute: number[]) { if (filtered) { // Jump to one iteration before next day - this.minute += - Math.floor((1439 - (this.hour * 60 + this.minute)) / minutes) * minutes; + this.minute += Math.floor((1439 - (this.hour * 60 + this.minute)) / minutes) * minutes; } for (;;) { @@ -176,29 +154,16 @@ export class DateTime extends Time { this.addHours(hourDiv, false, byhour); } - if ( - (empty(byhour) || byhour.includes(this.hour)) && - (empty(byminute) || byminute.includes(this.minute)) - ) { + if ((empty(byhour) || byhour.includes(this.hour)) && (empty(byminute) || byminute.includes(this.minute))) { break; } } } - public addSeconds( - seconds: number, - filtered: boolean, - byhour: number[], - byminute: number[], - bysecond: number[], - ) { + public addSeconds(seconds: number, filtered: boolean, byhour: number[], byminute: number[], bysecond: number[]) { if (filtered) { // Jump to one iteration before next day - this.second += - Math.floor( - (86399 - (this.hour * 3600 + this.minute * 60 + this.second)) / - seconds, - ) * seconds; + this.second += Math.floor((86399 - (this.hour * 3600 + this.minute * 60 + this.second)) / seconds) * seconds; } for (;;) { diff --git a/src/datewithzone.ts b/src/datewithzone.ts deleted file mode 100644 index 4645b280..00000000 --- a/src/datewithzone.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { dateInTimeZone, timeToUntilString } from './dateutil'; - -export class DateWithZone { - public date: Date; - public tzid?: string | null; - - constructor(date: Date, tzid?: string | null) { - if (Number.isNaN(date.getTime())) { - throw new RangeError('Invalid date passed to DateWithZone'); - } - this.date = date; - this.tzid = tzid; - } - - private get isUTC() { - return !this.tzid || this.tzid.toUpperCase() === 'UTC'; - } - - public toString() { - const datestr = timeToUntilString(this.date.getTime(), this.isUTC); - if (!this.isUTC) { - return `;TZID=${this.tzid}:${datestr}`; - } - - return `:${datestr}`; - } - - public getTime() { - return this.date.getTime(); - } - - public rezonedDate() { - if (this.isUTC) { - return this.date; - } - - return dateInTimeZone(this.date, this.tzid!); - } -} diff --git a/src/helpers.ts b/src/helpers.ts index 6e936b23..25ead6f7 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -4,11 +4,13 @@ import { ALL_WEEKDAYS, type WeekdayStr } from './weekday'; -export const isPresent = (value?: T | null | undefined): value is T => - value !== null && value !== undefined; +export const isDate = (value: unknown): value is Date => value instanceof Date; -export const isNumber = (value: unknown): value is number => - typeof value === 'number'; +export const isValidDate = (value: unknown): value is Date => isDate(value) && !Number.isNaN(value.getTime()); + +export const isPresent = (value?: T | null | undefined): value is T => value !== null && value !== undefined; + +export const isNumber = (value: unknown): value is number => typeof value === 'number'; export const isWeekdayStr = (value: unknown): value is WeekdayStr => typeof value === 'string' && ALL_WEEKDAYS.includes(value as WeekdayStr); @@ -53,9 +55,7 @@ export const toArray = (item: T | T[]): T[] => { */ export const split = (str: string, sep: string, num: number) => { const splits = str.split(sep); - return num - ? splits.slice(0, num).concat([splits.slice(num).join(sep)]) - : splits; + return num ? splits.slice(0, num).concat([splits.slice(num).join(sep)]) : splits; }; /** @@ -87,8 +87,7 @@ export const divmod = (a: number, b: number) => ({ mod: pymod(a, b), }); -export const empty = (obj: T[] | null | undefined) => - !isPresent(obj) || obj.length === 0; +export const empty = (obj: T[] | null | undefined) => !isPresent(obj) || obj.length === 0; /** * Python-like boolean @@ -97,5 +96,4 @@ export const empty = (obj: T[] | null | undefined) => * the fact that in Python an empty list's/tuple's * boolean value is False, whereas in JS it's true */ -export const notEmpty = (obj: T[] | null | undefined): obj is T[] => - !empty(obj); +export const notEmpty = (obj: T[] | null | undefined): obj is T[] => !empty(obj); diff --git a/src/index.ts b/src/index.ts index 17e697e8..ab4b659c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,24 +1,24 @@ /* ! * rrule.js - Library for working with recurrence rules for calendar dates. - * https://github.com/offload-project/rrule + * https://github.com/shavonn/rrule * * Copyright 2010, Jakub Roztocil and Lars Schoning * Copyright 2026, Shavonn Brown * Licenced under the BSD licence. - * https://github.com/offload-project/rrule/blob/main/LICENSE + * https://github.com/shavonn/rrule/blob/main/LICENSE * * Based on: * python-dateutil - Extensions to the standard Python datetime module. * Copyright (c) 2003-2011 - Gustavo Niemeyer * Copyright (c) 2012 - Tomi Pieviläinen - * https://github.com/offload-project/rrule/blob/main/LICENSE + * https://github.com/shavonn/rrule/blob/main/LICENSE * */ -export { datetime } from './dateutil'; +export { datetime } from './date'; +export { type RRuleStrOptions, rrulestr } from './parse/rrulestr'; export { RRule } from './rrule'; export { RRuleBase } from './rrulebase'; export { RRuleSet } from './rruleset'; -export { type RRuleStrOptions, rrulestr } from './rrulestr'; export { type ByWeekday, Frequency, type Options } from './types'; export { ALL_WEEKDAYS, Weekday, type WeekdayStr } from './weekday'; diff --git a/src/iter/index.ts b/src/iter/index.ts index 3800ce65..5321446c 100644 --- a/src/iter/index.ts +++ b/src/iter/index.ts @@ -1,22 +1,14 @@ +import { combine, DateWithZone, fromOrdinal, MAXYEAR } from '../date'; import { DateTime, type Time } from '../datetime'; -import { combine, fromOrdinal, MAXYEAR } from '../dateutil'; -import { DateWithZone } from '../datewithzone'; import { isPresent, notEmpty } from '../helpers'; +import { buildTimeset } from '../iterinfo'; import Iterinfo from '../iterinfo/index'; import type IterResult from '../iterresult'; -import { buildTimeset } from '../parseoptions'; import { RRule } from '../rrule'; -import { - freqIsDailyOrGreater, - type ParsedOptions, - type QueryMethodTypes, -} from '../types'; +import { freqIsDailyOrGreater, type ParsedOptions, type QueryMethodTypes } from '../types'; import { buildPoslist } from './poslist'; -export function iter( - iterResult: IterResult, - options: ParsedOptions, -) { +export function iter(iterResult: IterResult, options: ParsedOptions) { const { dtstart, freq, interval, until, bysetpos } = options; let count = options.count; @@ -32,11 +24,7 @@ export function iter( let timeset = makeTimeset(ii, counterDate, options); for (;;) { - const [dayset, start, end] = ii.getdayset(freq)( - counterDate.year, - counterDate.month, - counterDate.day, - ); + const [dayset, start, end] = ii.getdayset(freq)(counterDate.year, counterDate.month, counterDate.day); const filtered = removeFilteredDays(dayset, start, end, ii, options); @@ -100,32 +88,15 @@ export function iter( } if (!freqIsDailyOrGreater(freq)) { - timeset = ii.gettimeset(freq)( - counterDate.hour, - counterDate.minute, - counterDate.second, - 0, - ); + timeset = ii.gettimeset(freq)(counterDate.hour, counterDate.minute, counterDate.second, 0); } ii.rebuild(counterDate.year, counterDate.month); } } -function isFiltered( - ii: Iterinfo, - currentDay: number, - options: ParsedOptions, -): boolean { - const { - bymonth, - byweekno, - byweekday, - byeaster, - bymonthday, - bynmonthday, - byyearday, - } = options; +function isFiltered(ii: Iterinfo, currentDay: number, options: ParsedOptions): boolean { + const { bymonth, byweekno, byweekday, byeaster, bymonthday, bynmonthday, byyearday } = options; return ( (notEmpty(bymonth) && !bymonth.includes(ii.mmask[currentDay]!)) || @@ -174,11 +145,7 @@ function removeFilteredDays( return filtered; } -function makeTimeset( - ii: Iterinfo, - counterDate: DateTime, - options: ParsedOptions, -): Time[] | null { +function makeTimeset(ii: Iterinfo, counterDate: DateTime, options: ParsedOptions): Time[] | null { const { freq, byhour, byminute, bysecond } = options; if (freqIsDailyOrGreater(freq)) { @@ -186,23 +153,12 @@ function makeTimeset( } if ( - (freq >= RRule.HOURLY && - notEmpty(byhour) && - !byhour.includes(counterDate.hour)) || - (freq >= RRule.MINUTELY && - notEmpty(byminute) && - !byminute.includes(counterDate.minute)) || - (freq >= RRule.SECONDLY && - notEmpty(bysecond) && - !bysecond.includes(counterDate.second)) + (freq >= RRule.HOURLY && notEmpty(byhour) && !byhour.includes(counterDate.hour)) || + (freq >= RRule.MINUTELY && notEmpty(byminute) && !byminute.includes(counterDate.minute)) || + (freq >= RRule.SECONDLY && notEmpty(bysecond) && !bysecond.includes(counterDate.second)) ) { return []; } - return ii.gettimeset(freq)( - counterDate.hour, - counterDate.minute, - counterDate.second, - counterDate.millisecond, - ); + return ii.gettimeset(freq)(counterDate.hour, counterDate.minute, counterDate.second, counterDate.millisecond); } diff --git a/src/iter/poslist.ts b/src/iter/poslist.ts index 4d97f899..a79ceafb 100644 --- a/src/iter/poslist.ts +++ b/src/iter/poslist.ts @@ -1,5 +1,5 @@ +import { combine, fromOrdinal, sort } from '../date'; import type { Time } from '../datetime'; -import { combine, fromOrdinal, sort } from '../dateutil'; import { isPresent, pymod } from '../helpers'; import type Iterinfo from '../iterinfo/index'; @@ -41,8 +41,6 @@ export function buildPoslist( const time = timeset[timepos]!; const date = fromOrdinal(ii.yearordinal + i); const res = combine(date, time); - // XXX: can this ever be in the array? - // - compare the actual date instead? if (!poslist.includes(res)) poslist.push(res); } diff --git a/src/iterset.ts b/src/iter/set.ts similarity index 87% rename from src/iterset.ts rename to src/iter/set.ts index 5cbcb859..b76ea832 100644 --- a/src/iterset.ts +++ b/src/iter/set.ts @@ -1,9 +1,8 @@ -import { sort } from './dateutil'; -import { DateWithZone } from './datewithzone'; -import { iter } from './iter'; -import type IterResult from './iterresult'; -import type { RRule } from './rrule'; -import type { IterResultType, QueryMethodTypes } from './types'; +import { DateWithZone, sort } from '../date'; +import type IterResult from '../iterresult'; +import type { RRule } from '../rrule'; +import type { IterResultType, QueryMethodTypes } from '../types'; +import { iter } from '.'; export function iterSet( iterResult: IterResult, diff --git a/src/iterinfo/index.ts b/src/iterinfo/index.ts index b08120d6..8d52ac73 100644 --- a/src/iterinfo/index.ts +++ b/src/iterinfo/index.ts @@ -1,7 +1,7 @@ +import { datetime, sort, toOrdinal } from '../date'; import { Time } from '../datetime'; -import { datetime, sort, toOrdinal } from '../dateutil'; import { isPresent, notEmpty, range, repeat } from '../helpers'; -import { Frequency, type ParsedOptions } from '../types'; +import { Frequency, freqIsDailyOrGreater, type ParsedOptions } from '../types'; import { easter } from './easter'; import { type MonthInfo, rebuildMonth } from './monthinfo'; import { rebuildYear, type YearInfo } from './yearinfo'; @@ -18,7 +18,6 @@ export default class Iterinfo { public monthinfo!: MonthInfo; public eastermask!: number[] | null; - // eslint-disable-next-line no-empty-function constructor(private options: ParsedOptions) {} rebuild(year: number, month: number) { @@ -28,19 +27,9 @@ export default class Iterinfo { this.yearinfo = rebuildYear(year, options); } - if ( - notEmpty(options.bynweekday) && - (month !== this.lastmonth || year !== this.lastyear) - ) { + if (notEmpty(options.bynweekday) && (month !== this.lastmonth || year !== this.lastyear)) { const { yearlen, mrange, wdaymask } = this.yearinfo; - this.monthinfo = rebuildMonth( - year, - month, - yearlen, - mrange, - wdaymask, - options, - ); + this.monthinfo = rebuildMonth(year, month, yearlen, mrange, wdaymask, options); } if (isPresent(options.byeaster)) { @@ -138,9 +127,7 @@ export default class Iterinfo { } mtimeset(hour: number, minute: number, _: number, millisecond: number) { - const set = this.options.bysecond.map( - (second) => new Time(hour, minute, second, millisecond), - ); + const set = this.options.bysecond.map((second) => new Time(hour, minute, second, millisecond)); sort(set); return set; @@ -178,3 +165,21 @@ export default class Iterinfo { } } } + +export function buildTimeset(opts: ParsedOptions) { + const millisecondModulo = opts.dtstart.getTime() % 1000; + if (!freqIsDailyOrGreater(opts.freq)) { + return []; + } + + const timeset: Time[] = []; + opts.byhour.forEach((hour) => { + opts.byminute.forEach((minute) => { + opts.bysecond.forEach((second) => { + timeset.push(new Time(hour, minute, second, millisecondModulo)); + }); + }); + }); + + return timeset; +} diff --git a/src/iterinfo/yearinfo.ts b/src/iterinfo/yearinfo.ts index ca33df14..c11eee81 100644 --- a/src/iterinfo/yearinfo.ts +++ b/src/iterinfo/yearinfo.ts @@ -1,4 +1,4 @@ -import { datetime, getWeekday, isLeapYear, toOrdinal } from '../dateutil'; +import { datetime, getWeekday, isLeapYear, toOrdinal } from '../date'; import { empty, pymod, repeat } from '../helpers'; import { M365MASK, @@ -95,7 +95,6 @@ export function rebuildYear(year: number, options: ParsedOptions) { if (options.byweekno.includes(1)) { // Check week number 1 of next year as well - // orig-TODO : Check -numweeks for next year. let i = no1wkst + numweeks * 7; if (no1wkst !== firstwkst) i -= 7 - firstwkst; if (i < yearlen) { diff --git a/src/iterresult.ts b/src/iterresult.ts index 88a4fd08..005fd47a 100644 --- a/src/iterresult.ts +++ b/src/iterresult.ts @@ -28,12 +28,8 @@ export default class IterResult { this.args = args; if (method === 'between') { - this.maxDate = args.inc! - ? args.before! - : new Date(args.before!.getTime() - 1); - this.minDate = args.inc! - ? args.after! - : new Date(args.after!.getTime() + 1); + this.maxDate = args.inc! ? args.before! : new Date(args.before!.getTime() - 1); + this.minDate = args.inc! ? args.after! : new Date(args.after!.getTime() + 1); } else if (method === 'before') { this.maxDate = args.inc! ? args.dt! : new Date(args.dt!.getTime() - 1); } else if (method === 'after') { @@ -99,3 +95,27 @@ export default class IterResult { return new IterResult(this.method, this.args); } } + +type Iterator = (d: Date, len: number) => boolean; + +/** + * IterResult subclass that calls a callback function on each add, + * and stops iterating when the callback returns false. + */ +export class CallbackIterResult extends IterResult<'all' | 'between'> { + private iterator: Iterator; + + constructor(method: 'all' | 'between', args: Partial, iterator: Iterator) { + super(method, args); + + this.iterator = iterator; + } + + add(date: Date) { + if (this.iterator(date, this._result.length)) { + this._result.push(date); + return true; + } + return false; + } +} diff --git a/src/masks.ts b/src/masks.ts index 37e8c285..0dd332d6 100644 --- a/src/masks.ts +++ b/src/masks.ts @@ -121,14 +121,4 @@ const WDAYMASK = (() => { return wdaymask; })(); -export { - WDAYMASK, - M365MASK, - M365RANGE, - M366MASK, - M366RANGE, - MDAY365MASK, - MDAY366MASK, - NMDAY365MASK, - NMDAY366MASK, -}; +export { WDAYMASK, M365MASK, M365RANGE, M366MASK, M366RANGE, MDAY365MASK, MDAY366MASK, NMDAY365MASK, NMDAY366MASK }; diff --git a/src/nlp/i18n.ts b/src/nlp/i18n.ts index 58c38a9a..18c8d35e 100644 --- a/src/nlp/i18n.ts +++ b/src/nlp/i18n.ts @@ -11,15 +11,7 @@ export interface Language { } const ENGLISH: Language = { - dayNames: [ - 'Sunday', - 'Monday', - 'Tuesday', - 'Wednesday', - 'Thursday', - 'Friday', - 'Saturday', - ], + dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], monthNames: [ 'January', 'February', diff --git a/src/nlp/index.ts b/src/nlp/index.ts index 2f21eea5..b7b3a0a2 100644 --- a/src/nlp/index.ts +++ b/src/nlp/index.ts @@ -6,12 +6,12 @@ import ToText, { type DateFormatter, type GetText } from './totext'; /* ! * rrule.js - Library for working with recurrence rules for calendar dates. - * https://github.com/offload-project/rrule + * https://github.com/shavonn/rrule * * Copyright 2010, Jakub Roztocil and Lars Schoning * Copyright 2026, Shavonn Brown * Licenced under the BSD license. - * https://github.com/offload-project/rrule/blob/main/LICENSE + * https://github.com/shavonn/rrule/blob/main/LICENSE * */ @@ -97,17 +97,9 @@ import ToText, { type DateFormatter, type GetText } from './totext'; * @param language * @return {Object, Boolean} the rule, or null. */ -const fromText = (text: string, language: Language = ENGLISH) => - new RRule(parseText(text, language) || undefined); +const fromText = (text: string, language: Language = ENGLISH) => new RRule(parseText(text, language) || undefined); -const common = [ - 'count', - 'until', - 'interval', - 'byweekday', - 'bymonthday', - 'bymonth', -]; +const common = ['count', 'until', 'interval', 'byweekday', 'bymonthday', 'bymonth']; ToText.IMPLEMENTED = []; ToText.IMPLEMENTED[Frequency.HOURLY] = common; @@ -121,12 +113,8 @@ ToText.IMPLEMENTED[Frequency.YEARLY] = ['byweekno', 'byyearday'].concat(common); // Export // ============================================================================= -const toText = ( - rrule: RRule, - gettext?: GetText, - language?: Language, - dateFormatter?: DateFormatter, -) => new ToText(rrule, gettext, language, dateFormatter).toString(); +const toText = (rrule: RRule, gettext?: GetText, language?: Language, dateFormatter?: DateFormatter) => + new ToText(rrule, gettext, language, dateFormatter).toString(); const { isFullyConvertible } = ToText; diff --git a/src/nlp/parsetext.ts b/src/nlp/parsetext.ts index 9e96df32..8b09d391 100644 --- a/src/nlp/parsetext.ts +++ b/src/nlp/parsetext.ts @@ -120,8 +120,6 @@ export default function parseText(text: string, language: Language = ENGLISH) { } break; - // FIXME Note: every 2 weekdays != every two weeks on weekdays. - // DAILY on weekdays is not a valid rule case 'weekday(s)': options.freq = RRule.WEEKLY; options.byweekday = [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR]; @@ -179,22 +177,17 @@ export default function parseText(text: string, language: Language = ENGLISH) { case 'saturday': case 'sunday': { options.freq = RRule.WEEKLY; - const key: WeekdayStr = ttr.symbol - .substr(0, 2) - .toUpperCase() as WeekdayStr; + const key: WeekdayStr = ttr.symbol.substr(0, 2).toUpperCase() as WeekdayStr; options.byweekday = [RRule[key]]; if (!ttr.nextSymbol()) return; - // TODO check for duplicates while (ttr.accept('comma')) { if (ttr.isDone()) throw new Error('Unexpected end'); const wkd = decodeWKD() as keyof typeof RRule; if (!wkd) { - throw new Error( - `Unexpected symbol ${ttr.symbol}, expected weekday`, - ); + throw new Error(`Unexpected symbol ${ttr.symbol}, expected weekday`); } options.byweekday.push(RRule[wkd] as ByWeekday); @@ -223,7 +216,6 @@ export default function parseText(text: string, language: Language = ENGLISH) { if (!ttr.nextSymbol()) return; - // TODO check for duplicates while (ttr.accept('comma')) { if (ttr.isDone()) throw new Error('Unexpected end'); @@ -257,14 +249,10 @@ export default function parseText(text: string, language: Language = ENGLISH) { // nth | if (nth) { - // ttr.nextSymbol() - if (wkd) { ttr.nextSymbol(); if (!options.byweekday) options.byweekday = [] as ByWeekday[]; - (options.byweekday as ByWeekday[]).push( - RRule[wkd as WeekdayStr].nth(nth), - ); + (options.byweekday as ByWeekday[]).push(RRule[wkd as WeekdayStr].nth(nth)); } else { if (!options.bymonthday) options.bymonthday = [] as number[]; (options.bymonthday as number[]).push(nth); @@ -278,29 +266,19 @@ export default function parseText(text: string, language: Language = ENGLISH) { } else if (ttr.symbol === 'weekday(s)') { ttr.nextSymbol(); if (!options.byweekday) { - options.byweekday = [ - RRule.MO, - RRule.TU, - RRule.WE, - RRule.TH, - RRule.FR, - ]; + options.byweekday = [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR]; } } else if (ttr.symbol === 'week(s)') { ttr.nextSymbol(); let n = ttr.acceptNumber(); if (!n) { - throw new Error( - `Unexpected symbol ${ttr.symbol}, expected week number`, - ); + throw new Error(`Unexpected symbol ${ttr.symbol}, expected week number`); } options.byweekno = [parseInt(n[0], 10)]; while (ttr.accept('comma')) { n = ttr.acceptNumber(); if (!n) { - throw new Error( - `Unexpected symbol ${ttr.symbol}; expected monthday`, - ); + throw new Error(`Unexpected symbol ${ttr.symbol}; expected monthday`); } options.byweekno.push(parseInt(n[0], 10)); } @@ -437,7 +415,6 @@ export default function parseText(text: string, language: Language = ENGLISH) { } else if (ttr.accept('for')) { options.count = parseInt(ttr.value![0]!, 10); ttr.expect('number'); - // ttr.expect('times') } } } diff --git a/src/nlp/totext.ts b/src/nlp/totext.ts index 89ffb85b..5116d57a 100644 --- a/src/nlp/totext.ts +++ b/src/nlp/totext.ts @@ -21,17 +21,9 @@ export type GetText = (id: string | number | Weekday) => string; const defaultGetText: GetText = (id) => id.toString(); -export type DateFormatter = ( - year: number, - month: string, - day: number, -) => string; - -const defaultDateFormatter: DateFormatter = ( - year: number, - month: string, - day: number, -) => `${month} ${day}, ${year}`; +export type DateFormatter = (year: number, month: string, day: number) => string; + +const defaultDateFormatter: DateFormatter = (year: number, month: string, day: number) => `${month} ${day}, ${year}`; /** * @@ -90,12 +82,8 @@ export default class ToText { const days = String(byweekday); this.byweekday = { - allWeeks: byweekday.filter( - (weekday: ByWeekday) => !(weekday as Weekday).n, - ), - someWeeks: byweekday.filter((weekday: ByWeekday) => - Boolean((weekday as Weekday).n), - ), + allWeeks: byweekday.filter((weekday: ByWeekday) => !(weekday as Weekday).n), + someWeeks: byweekday.filter((weekday: ByWeekday) => Boolean((weekday as Weekday).n)), isWeekdays: days.indexOf('MO') !== -1 && days.indexOf('TU') !== -1 && @@ -114,8 +102,7 @@ export default class ToText { days.indexOf('SU') !== -1, }; - const sortWeekDays = (a: ByWeekday, b: ByWeekday) => - (a as Weekday).weekday - (b as Weekday).weekday; + const sortWeekDays = (a: ByWeekday, b: ByWeekday) => (a as Weekday).weekday - (b as Weekday).weekday; this.byweekday.allWeeks!.sort(sortWeekDays); this.byweekday.someWeeks!.sort(sortWeekDays); @@ -166,26 +153,19 @@ export default class ToText { } this.text = [gettext('every')]; - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error + // @ts-expect-error - dynamic method dispatch via frequency name this[RRule.FREQUENCIES[this.options.freq]](); if (this.options.until) { this.add(gettext('until')); const until = this.options.until; this.add( - this.dateFormatter( - until.getUTCFullYear(), - this.language.monthNames[until.getUTCMonth()]!, - until.getUTCDate(), - ), + this.dateFormatter(until.getUTCFullYear(), this.language.monthNames[until.getUTCMonth()]!, until.getUTCDate()), ); } else if (this.options.count) { this.add(gettext('for')) .add(this.options.count.toString()) - .add( - this.plural(this.options.count) ? gettext('times') : gettext('time'), - ); + .add(this.plural(this.options.count) ? gettext('times') : gettext('time')); } if (this.origOptions.dtstart) { @@ -211,9 +191,7 @@ export default class ToText { if (this.options.interval !== 1) this.add(this.options.interval.toString()); - this.add( - this.plural(this.options.interval) ? gettext('hours') : gettext('hour'), - ); + this.add(this.plural(this.options.interval) ? gettext('hours') : gettext('hour')); } MINUTELY() { @@ -221,11 +199,7 @@ export default class ToText { if (this.options.interval !== 1) this.add(this.options.interval.toString()); - this.add( - this.plural(this.options.interval) - ? gettext('minutes') - : gettext('minute'), - ); + this.add(this.plural(this.options.interval) ? gettext('minutes') : gettext('minute')); } DAILY() { @@ -234,15 +208,9 @@ export default class ToText { if (this.options.interval !== 1) this.add(this.options.interval.toString()); if (this.byweekday?.isWeekdays) { - this.add( - this.plural(this.options.interval) - ? gettext('weekdays') - : gettext('weekday'), - ); + this.add(this.plural(this.options.interval) ? gettext('weekdays') : gettext('weekday')); } else { - this.add( - this.plural(this.options.interval) ? gettext('days') : gettext('day'), - ); + this.add(this.plural(this.options.interval) ? gettext('days') : gettext('day')); } if (this.origOptions.bymonth) { @@ -270,18 +238,12 @@ export default class ToText { if (this.byweekday?.isWeekdays) { if (this.options.interval === 1) { - this.add( - this.plural(this.options.interval) - ? gettext('weekdays') - : gettext('weekday'), - ); + this.add(this.plural(this.options.interval) ? gettext('weekdays') : gettext('weekday')); } else { this.add(gettext('on')).add(gettext('weekdays')); } } else if (this.byweekday?.isEveryDay) { - this.add( - this.plural(this.options.interval) ? gettext('days') : gettext('day'), - ); + this.add(this.plural(this.options.interval) ? gettext('days') : gettext('day')); } else { if (this.options.interval === 1) this.add(gettext('week')); @@ -309,19 +271,13 @@ export default class ToText { if (this.options.interval !== 1) { this.add(this.options.interval.toString()).add(gettext('months')); if (this.plural(this.options.interval)) this.add(gettext('in')); - } else { - // this.add(gettext('MONTH')) } this._bymonth(); } else { if (this.options.interval !== 1) { this.add(this.options.interval.toString()); } - this.add( - this.plural(this.options.interval) - ? gettext('months') - : gettext('month'), - ); + this.add(this.plural(this.options.interval) ? gettext('months') : gettext('month')); } if (this.bymonthday) { this._bymonthday(); @@ -339,17 +295,13 @@ export default class ToText { if (this.options.interval !== 1) { this.add(this.options.interval.toString()); this.add(gettext('years')); - } else { - // this.add(gettext('YEAR')) } this._bymonth(); } else { if (this.options.interval !== 1) { this.add(this.options.interval.toString()); } - this.add( - this.plural(this.options.interval) ? gettext('years') : gettext('year'), - ); + this.add(this.plural(this.options.interval) ? gettext('years') : gettext('year')); } if (this.bymonthday) { @@ -360,23 +312,13 @@ export default class ToText { if (this.options.byyearday) { this.add(gettext('on the')) - .add( - this.list( - this.options.byyearday, - this.nth as GetText, - gettext('and'), - ), - ) + .add(this.list(this.options.byyearday, this.nth as GetText, gettext('and'))) .add(gettext('day')); } if (this.options.byweekno) { this.add(gettext('in')) - .add( - this.plural((this.options.byweekno as number[]).length) - ? gettext('weeks') - : gettext('week'), - ) + .add(this.plural((this.options.byweekno as number[]).length) ? gettext('weeks') : gettext('week')) .add(this.list(this.options.byweekno, undefined, gettext('and'))); } } @@ -385,40 +327,25 @@ export default class ToText { const gettext = this.gettext; if (this.byweekday?.allWeeks) { this.add(gettext('on')) - .add( - this.list( - this.byweekday.allWeeks, - this.weekdaytext as GetText, - gettext('or'), - ), - ) + .add(this.list(this.byweekday.allWeeks, this.weekdaytext as GetText, gettext('or'))) .add(gettext('the')) .add(this.list(this.bymonthday!, this.nth as GetText, gettext('or'))); } else { - this.add(gettext('on the')).add( - this.list(this.bymonthday!, this.nth as GetText, gettext('and')), - ); + this.add(gettext('on the')).add(this.list(this.bymonthday!, this.nth as GetText, gettext('and'))); } - // this.add(gettext('DAY')) } private _byweekday() { const gettext = this.gettext; if (this.byweekday!.allWeeks && !this.byweekday!.isWeekdays) { - this.add(gettext('on')).add( - this.list(this.byweekday!.allWeeks, this.weekdaytext as GetText), - ); + this.add(gettext('on')).add(this.list(this.byweekday!.allWeeks, this.weekdaytext as GetText)); } if (this.byweekday!.someWeeks) { if (this.byweekday!.allWeeks) this.add(gettext('and')); this.add(gettext('on the')).add( - this.list( - this.byweekday!.someWeeks, - this.weekdaytext as GetText, - gettext('and'), - ), + this.list(this.byweekday!.someWeeks, this.weekdaytext as GetText, gettext('and')), ); } } @@ -426,19 +353,11 @@ export default class ToText { private _byhour() { const gettext = this.gettext; - this.add(gettext('at')).add( - this.list(this.origOptions.byhour!, undefined, gettext('and')), - ); + this.add(gettext('at')).add(this.list(this.origOptions.byhour!, undefined, gettext('and'))); } private _bymonth() { - this.add( - this.list( - this.options.bymonth, - this.monthtext as unknown as GetText, - this.gettext('and'), - ), - ); + this.add(this.list(this.options.bymonth, this.monthtext as unknown as GetText, this.gettext('and'))); } nth(n: number | string) { @@ -476,10 +395,7 @@ export default class ToText { weekdaytext(wday: Weekday | number) { const weekday = isNumber(wday) ? (wday + 1) % 7 : wday.getJsWeekday(); - return ( - ((wday as Weekday).n ? `${this.nth((wday as Weekday).n!)} ` : '') + - this.language.dayNames[weekday] - ); + return ((wday as Weekday).n ? `${this.nth((wday as Weekday).n!)} ` : '') + this.language.dayNames[weekday]; } plural(n: number) { @@ -492,20 +408,11 @@ export default class ToText { return this; } - list( - arr: ByWeekday | ByWeekday[], - callback?: GetText, - finalDelim?: string, - delim = ',', - ) { + list(arr: ByWeekday | ByWeekday[], callback?: GetText, finalDelim?: string, delim = ',') { if (!isArray(arr)) { arr = [arr]; } - const delimJoin = ( - array: string[], - delimiter: string, - finalDelimiter: string, - ) => { + const delimJoin = (array: string[], delimiter: string, finalDelimiter: string) => { let list = ''; for (let i = 0; i < array.length; i++) { diff --git a/src/parseoptions.ts b/src/parse/options.ts similarity index 77% rename from src/parseoptions.ts rename to src/parse/options.ts index b70cc2d0..e1b1b3a2 100644 --- a/src/parseoptions.ts +++ b/src/parse/options.ts @@ -1,19 +1,8 @@ -import { Time } from './datetime'; -import { getWeekday, isDate, isValidDate } from './dateutil'; -import { - isArray, - isNumber, - isPresent, - isWeekdayStr, - notEmpty, -} from './helpers'; -import { DEFAULT_OPTIONS, defaultKeys, RRule } from './rrule'; -import { - freqIsDailyOrGreater, - type Options, - type ParsedOptions, -} from './types'; -import { Weekday } from './weekday'; +import { getWeekday } from '../date'; +import { isArray, isDate, isNumber, isPresent, isValidDate, isWeekdayStr, notEmpty } from '../helpers'; +import { DEFAULT_OPTIONS, defaultKeys, RRule } from '../rrule'; +import type { Options, ParsedOptions } from '../types'; +import { Weekday } from '../weekday'; export function initializeOptions(options: Partial) { const invalid: string[] = []; @@ -58,9 +47,7 @@ export function parseOptions(options: Partial) { for (const v of opts.bysetpos) { if (v === 0 || !(v >= -366 && v <= 366)) { - throw new Error( - 'bysetpos must be between 1 and 366,' + ' or between -366 and -1', - ); + throw new Error('bysetpos must be between 1 and 366,' + ' or between -366 and -1'); } } } @@ -96,11 +83,7 @@ export function parseOptions(options: Partial) { } // byyearday - if ( - isPresent(opts.byyearday) && - !isArray(opts.byyearday) && - isNumber(opts.byyearday) - ) { + if (isPresent(opts.byyearday) && !isArray(opts.byyearday) && isNumber(opts.byyearday)) { opts.byyearday = [opts.byyearday]; } @@ -176,45 +159,24 @@ export function parseOptions(options: Partial) { // byhour if (!isPresent(opts.byhour)) { - opts.byhour = - opts.freq < RRule.HOURLY ? [opts.dtstart.getUTCHours()] : null; + opts.byhour = opts.freq < RRule.HOURLY ? [opts.dtstart.getUTCHours()] : null; } else if (isNumber(opts.byhour)) { opts.byhour = [opts.byhour]; } // byminute if (!isPresent(opts.byminute)) { - opts.byminute = - opts.freq < RRule.MINUTELY ? [opts.dtstart.getUTCMinutes()] : null; + opts.byminute = opts.freq < RRule.MINUTELY ? [opts.dtstart.getUTCMinutes()] : null; } else if (isNumber(opts.byminute)) { opts.byminute = [opts.byminute]; } // bysecond if (!isPresent(opts.bysecond)) { - opts.bysecond = - opts.freq < RRule.SECONDLY ? [opts.dtstart.getUTCSeconds()] : null; + opts.bysecond = opts.freq < RRule.SECONDLY ? [opts.dtstart.getUTCSeconds()] : null; } else if (isNumber(opts.bysecond)) { opts.bysecond = [opts.bysecond]; } return { parsedOptions: opts as ParsedOptions }; } - -export function buildTimeset(opts: ParsedOptions) { - const millisecondModulo = opts.dtstart.getTime() % 1000; - if (!freqIsDailyOrGreater(opts.freq)) { - return []; - } - - const timeset: Time[] = []; - opts.byhour.forEach((hour) => { - opts.byminute.forEach((minute) => { - opts.bysecond.forEach((second) => { - timeset.push(new Time(hour, minute, second, millisecondModulo)); - }); - }); - }); - - return timeset; -} diff --git a/src/rrulestr.ts b/src/parse/rrulestr.ts similarity index 84% rename from src/rrulestr.ts rename to src/parse/rrulestr.ts index 12304222..074d686e 100644 --- a/src/rrulestr.ts +++ b/src/parse/rrulestr.ts @@ -1,9 +1,9 @@ -import { untilStringToDate } from './dateutil'; -import { split } from './helpers'; -import { parseDtstart, parseString } from './parsestring'; -import { RRule } from './rrule'; -import { RRuleSet } from './rruleset'; -import type { Options } from './types'; +import { untilStringToDate } from '../date'; +import { split } from '../helpers'; +import { RRule } from '../rrule'; +import { RRuleSet } from '../rruleset'; +import type { Options } from '../types'; +import { parseDtstart, parseString } from './string'; export interface RRuleStrOptions { dtstart: Date | null; @@ -92,8 +92,7 @@ export function parseInput(s: string, options: Partial) { } function buildRule(s: string, options: Partial) { - const { rrulevals, rdatevals, exrulevals, exdatevals, dtstart, tzid } = - parseInput(s, options); + const { rrulevals, rdatevals, exrulevals, exdatevals, dtstart, tzid } = parseInput(s, options); const noCache = options.cache === false; @@ -102,13 +101,7 @@ function buildRule(s: string, options: Partial) { options.unfold = true; } - if ( - options.forceset || - rrulevals.length > 1 || - rdatevals.length || - exrulevals.length || - exdatevals.length - ) { + if (options.forceset || rrulevals.length > 1 || rdatevals.length || exrulevals.length || exdatevals.length) { const rset = new RRuleSet(noCache); rset.dtstart(dtstart); @@ -136,27 +129,16 @@ function buildRule(s: string, options: Partial) { const val = rrulevals[0] || {}; return new RRule( - groomRruleOptions( - val, - val.dtstart || options.dtstart || dtstart, - val.tzid || options.tzid || tzid, - ), + groomRruleOptions(val, val.dtstart || options.dtstart || dtstart, val.tzid || options.tzid || tzid), noCache, ); } -export function rrulestr( - s: string, - options: Partial = {}, -): RRule | RRuleSet { +export function rrulestr(s: string, options: Partial = {}): RRule | RRuleSet { return buildRule(s, initializeOptions(options)); } -function groomRruleOptions( - val: Partial, - dtstart?: Date | null, - tzid?: string | null, -) { +function groomRruleOptions(val: Partial, dtstart?: Date | null, tzid?: string | null) { return { ...val, dtstart, @@ -167,9 +149,7 @@ function groomRruleOptions( function initializeOptions(options: Partial) { const invalid: string[] = []; const keys = Object.keys(options) as (keyof typeof options)[]; - const defaultKeys = Object.keys( - DEFAULT_OPTIONS, - ) as (keyof typeof DEFAULT_OPTIONS)[]; + const defaultKeys = Object.keys(DEFAULT_OPTIONS) as (keyof typeof DEFAULT_OPTIONS)[]; keys.forEach((key) => { if (!defaultKeys.includes(key)) invalid.push(key); @@ -222,7 +202,6 @@ function splitIntoLines(s: string, unfold = false) { const lines = s.split('\n'); let i = 0; while (i < lines.length) { - // TODO lines[i] = lines[i]!.replace(/\s+$/g, ''); const line = lines[i]; if (!line) { diff --git a/src/parsestring.ts b/src/parse/string.ts similarity index 94% rename from src/parsestring.ts rename to src/parse/string.ts index 1d75acdc..fd3e70bb 100644 --- a/src/parsestring.ts +++ b/src/parse/string.ts @@ -1,7 +1,7 @@ -import { untilStringToDate } from './dateutil'; -import { Days } from './rrule'; -import { Frequency, type Options } from './types'; -import { Weekday } from './weekday'; +import { untilStringToDate } from '../date'; +import { Days } from '../rrule'; +import { Frequency, type Options } from '../types'; +import { Weekday } from '../weekday'; export function parseString(rfcString: string): Partial { const options = rfcString @@ -14,9 +14,7 @@ export function parseString(rfcString: string): Partial { export function parseDtstart(line: string) { const options: Partial = {}; - const dtstartWithZone = /DTSTART(?:;TZID=([^:=]+?))?(?::|=)([^;\s]+)/i.exec( - line, - ); + const dtstartWithZone = /DTSTART(?:;TZID=([^:=]+?))?(?::|=)([^;\s]+)/i.exec(line); if (!dtstartWithZone) { return options; diff --git a/src/optionstostring.ts b/src/parse/stringify.ts similarity index 86% rename from src/optionstostring.ts rename to src/parse/stringify.ts index ab6594ce..f1801fe6 100644 --- a/src/optionstostring.ts +++ b/src/parse/stringify.ts @@ -1,9 +1,8 @@ -import { timeToUntilString } from './dateutil'; -import { DateWithZone } from './datewithzone'; -import { isArray, isNumber, isPresent, toArray } from './helpers'; -import { DEFAULT_OPTIONS, RRule } from './rrule'; -import type { Options } from './types'; -import { Weekday } from './weekday'; +import { DateWithZone, timeToUntilString } from '../date'; +import { isArray, isNumber, isPresent, toArray } from '../helpers'; +import { DEFAULT_OPTIONS, RRule } from '../rrule'; +import type { Options } from '../types'; +import { Weekday } from '../weekday'; export function optionsToString(options: Partial) { const rrule: string[][] = []; @@ -45,9 +44,7 @@ export function optionsToString(options: Partial) { */ key = 'BYDAY'; - outValue = toArray( - value as Weekday | number[] | number, - ) + outValue = toArray(value as Weekday | number[] | number) .map((wday) => { if (wday instanceof Weekday) { return wday; diff --git a/src/rrule.ts b/src/rrule.ts index 30f8e500..254a4632 100644 --- a/src/rrule.ts +++ b/src/rrule.ts @@ -3,17 +3,11 @@ import type IterResult from './iterresult'; import type { Language } from './nlp/i18n'; import { fromText, isFullyConvertible, parseText, toText } from './nlp/index'; import type { DateFormatter, GetText } from './nlp/totext'; -import { optionsToString } from './optionstostring'; -import { initializeOptions, parseOptions } from './parseoptions'; -import { parseString } from './parsestring'; +import { initializeOptions, parseOptions } from './parse/options'; +import { parseString } from './parse/string'; +import { optionsToString } from './parse/stringify'; import { RRuleBase } from './rrulebase'; -import { - Frequency, - type IterResultType, - type Options, - type ParsedOptions, - type QueryMethodTypes, -} from './types'; +import { Frequency, type IterResultType, type Options, type ParsedOptions, type QueryMethodTypes } from './types'; import { Weekday } from './weekday'; // ============================================================================= @@ -117,9 +111,7 @@ export class RRule extends RRuleBase { static optionsToString = optionsToString; - protected _iter( - iterResult: IterResult, - ): IterResultType { + protected _iter(iterResult: IterResult): IterResultType { return iter(iterResult, this.options); } @@ -137,11 +129,7 @@ export class RRule extends RRuleBase { * Will convert all rules described in nlp:ToText * to text. */ - toText( - gettext?: GetText, - language?: Language, - dateFormatter?: DateFormatter, - ) { + toText(gettext?: GetText, language?: Language, dateFormatter?: DateFormatter) { return toText(this, gettext, language, dateFormatter); } diff --git a/src/rrulebase.ts b/src/rrulebase.ts index 9f9c0977..82cc0b28 100644 --- a/src/rrulebase.ts +++ b/src/rrulebase.ts @@ -1,7 +1,6 @@ import { Cache, type CacheKeys } from './cache'; -import CallbackIterResult from './callbackiterresult'; -import { isValidDate } from './dateutil'; -import IterResult, { type IterArgs } from './iterresult'; +import { isValidDate } from './helpers'; +import IterResult, { CallbackIterResult, type IterArgs } from './iterresult'; import type { IterResultType, QueryMethods, QueryMethodTypes } from './types'; export abstract class RRuleBase implements QueryMethods { @@ -11,20 +10,14 @@ export abstract class RRuleBase implements QueryMethods { this._cache = noCache ? null : new Cache(); } - protected abstract _iter( - iterResult: IterResult, - ): IterResultType; + protected abstract _iter(iterResult: IterResult): IterResultType; private _cacheGet(what: CacheKeys | 'all', args?: Partial) { if (!this._cache) return false; return this._cache._cacheGet(what, args); } - public _cacheAdd( - what: CacheKeys | 'all', - value: Date[] | Date | null, - args?: Partial, - ) { + public _cacheAdd(what: CacheKeys | 'all', value: Date[] | Date | null, args?: Partial) { if (!this._cache) return; return this._cache._cacheAdd(what, value, args); } @@ -56,12 +49,7 @@ export abstract class RRuleBase implements QueryMethods { * * @return Array */ - between( - after: Date, - before: Date, - inc = false, - iterator?: (d: Date, len: number) => boolean, - ): Date[] { + between(after: Date, before: Date, inc = false, iterator?: (d: Date, len: number) => boolean): Date[] { if (!isValidDate(after) || !isValidDate(before)) { throw new Error('Invalid date passed in to RRule.between'); } diff --git a/src/rruleset.ts b/src/rruleset.ts index 1f473571..a35074ec 100644 --- a/src/rruleset.ts +++ b/src/rruleset.ts @@ -1,7 +1,7 @@ -import { sort, timeToUntilString } from './dateutil'; +import { sort, timeToUntilString } from './date'; +import { iterSet } from './iter/set'; import type IterResult from './iterresult'; -import { iterSet } from './iterset'; -import { optionsToString } from './optionstostring'; +import { optionsToString } from './parse/stringify'; import { RRule } from './rrule'; import { RRuleBase } from './rrulebase'; import type { IterResultType, QueryMethodTypes } from './types'; @@ -56,17 +56,8 @@ export class RRuleSet extends RRuleBase { return undefined; } - _iter( - iterResult: IterResult, - ): IterResultType { - return iterSet( - iterResult, - this._rrule, - this._exrule, - this._rdate, - this._exdate, - this.tzid(), - ); + _iter(iterResult: IterResult): IterResultType { + return iterSet(iterResult, this._rrule, this._exrule, this._rdate, this._exdate, this.tzid()); } /** @@ -221,17 +212,11 @@ function _addDate(date: Date, collection: Date[]) { } } -function rdatesToString( - param: string, - rdates: Date[], - tzid: string | undefined, -) { +function rdatesToString(param: string, rdates: Date[], tzid: string | undefined) { const isUTC = !tzid || tzid.toUpperCase() === 'UTC'; const header = isUTC ? `${param}:` : `${param};TZID=${tzid}:`; - const dateString = rdates - .map((rdate) => timeToUntilString(rdate.valueOf(), isUTC)) - .join(','); + const dateString = rdates.map((rdate) => timeToUntilString(rdate.valueOf(), isUTC)).join(','); return `${header}${dateString}`; } diff --git a/src/types.ts b/src/types.ts index abfa9d62..c357739c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,11 +8,7 @@ export interface QueryMethods { } export type QueryMethodTypes = keyof QueryMethods; -export type IterResultType = M extends - | 'all' - | 'between' - ? Date[] - : Date | null; +export type IterResultType = M extends 'all' | 'between' ? Date[] : Date | null; export enum Frequency { YEARLY = 0, @@ -26,11 +22,7 @@ export enum Frequency { export function freqIsDailyOrGreater( freq: Frequency, -): freq is - | Frequency.YEARLY - | Frequency.MONTHLY - | Frequency.WEEKLY - | Frequency.DAILY { +): freq is Frequency.YEARLY | Frequency.MONTHLY | Frequency.WEEKLY | Frequency.DAILY { return freq < Frequency.HOURLY; } diff --git a/src/weekday.ts b/src/weekday.ts index 7fc1f056..84be14a8 100644 --- a/src/weekday.ts +++ b/src/weekday.ts @@ -3,15 +3,7 @@ // ============================================================================= export type WeekdayStr = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU'; -export const ALL_WEEKDAYS: WeekdayStr[] = [ - 'MO', - 'TU', - 'WE', - 'TH', - 'FR', - 'SA', - 'SU', -]; +export const ALL_WEEKDAYS: WeekdayStr[] = ['MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU']; export class Weekday { public readonly weekday: number; diff --git a/test/dateutil.test.ts b/test/date.test.ts similarity index 77% rename from test/dateutil.test.ts rename to test/date.test.ts index 25ae72d5..163dd843 100644 --- a/test/dateutil.test.ts +++ b/test/date.test.ts @@ -1,4 +1,4 @@ -import { datetime, untilStringToDate } from '../src/dateutil'; +import { datetime, untilStringToDate } from '../src/date'; describe('untilStringToDate', () => { it('parses a date string', () => { diff --git a/test/datewithzone.test.ts b/test/datewithzone.test.ts index e3860921..b458666b 100644 --- a/test/datewithzone.test.ts +++ b/test/datewithzone.test.ts @@ -1,5 +1,5 @@ import { reset as resetMockDate, set as setMockDate } from 'mockdate'; -import { DateWithZone } from '../src/datewithzone'; +import { DateWithZone } from '../src/date'; import { datetime, expectedDate } from './lib/utils'; describe('toString', () => { @@ -24,9 +24,7 @@ it('returns the time of the date', () => { }); it('rejects invalid dates', () => { - expect(() => new DateWithZone(new Date(undefined))).toThrow( - 'Invalid date passed to DateWithZone', - ); + expect(() => new DateWithZone(new Date(undefined))).toThrow('Invalid date passed to DateWithZone'); }); describe('rezonedDate', () => { @@ -44,11 +42,7 @@ describe('rezonedDate', () => { const d = new Date(Date.parse('2010-10-05T11:00:00')); const dt = new DateWithZone(d, targetZone); expect(dt.rezonedDate()).toEqual( - expectedDate( - new Date(Date.parse('2010-10-05T11:00:00')), - currentLocalDate, - targetZone, - ), + expectedDate(new Date(Date.parse('2010-10-05T11:00:00')), currentLocalDate, targetZone), ); resetMockDate(); diff --git a/test/helpers.test.ts b/test/helpers.test.ts index 14aca7ff..441c8697 100644 --- a/test/helpers.test.ts +++ b/test/helpers.test.ts @@ -1,14 +1,4 @@ -import { - divmod, - empty, - isArray, - isNumber, - isPresent, - pymod, - range, - repeat, - split, -} from '../src/helpers'; +import { divmod, empty, isArray, isNumber, isPresent, pymod, range, repeat, split } from '../src/helpers'; describe('isPresent', () => { it('is false if object is null', () => { diff --git a/test/lib/utils.ts b/test/lib/utils.ts index 0c75f81d..9bb4b7cb 100644 --- a/test/lib/utils.ts +++ b/test/lib/utils.ts @@ -1,7 +1,7 @@ -export { datetime } from '../../src/dateutil'; +export { datetime } from '../../src/date'; import { RRule, RRuleBase } from '../../src'; -import { dateInTimeZone, datetime } from '../../src/dateutil'; +import { dateInTimeZone, datetime } from '../../src/date'; export const TEST_CTX = { ALSO_TESTSTRING_FUNCTIONS: false, @@ -10,10 +10,7 @@ export const TEST_CTX = { ALSO_TESTSUBSECOND_PRECISION: false, }; -const assertDatesEqual = ( - actual: Date | Date[] | null, - expected: Date | Date[], -) => { +const assertDatesEqual = (actual: Date | Date[] | null, expected: Date | Date[]) => { if (actual === null) actual = []; if (!Array.isArray(actual)) actual = [actual]; if (!Array.isArray(expected)) expected = [expected]; @@ -109,8 +106,7 @@ export const testRecurring = (( const maxTestDuration = 200; expect(time).toBeLessThan(maxTestDuration); - if (!Array.isArray(actualDates)) - actualDates = actualDates ? [actualDates] : []; + if (!Array.isArray(actualDates)) actualDates = actualDates ? [actualDates] : []; if (!Array.isArray(expectedDates)) expectedDates = [expectedDates]; assertDatesEqual(actualDates, expectedDates); @@ -119,9 +115,7 @@ export const testRecurring = (( // ========================================================== if (TEST_CTX.ALSO_TESTSUBSECOND_PRECISION) { - expect(actualDates.map(extractTime)).toEqual( - expectedDates.map(extractTime), - ); + expect(actualDates.map(extractTime)).toEqual(expectedDates.map(extractTime)); } if (TEST_CTX.ALSO_TESTSTRING_FUNCTIONS) { @@ -135,11 +129,7 @@ export const testRecurring = (( } } - if ( - TEST_CTX.ALSO_TESTNLP_FUNCTIONS && - rule instanceof RRule && - rule.isFullyConvertibleToText() - ) { + if (TEST_CTX.ALSO_TESTNLP_FUNCTIONS && rule instanceof RRule && rule.isFullyConvertibleToText()) { // Test fromText()/toText(). const str = rule.toString(); const text = rule.toText(); @@ -162,20 +152,12 @@ export const testRecurring = (( if (expectedDates.length > 2) { // Test between() assertDatesEqual( - rule.between( - expectedDates[0]!, - expectedDates[expectedDates.length - 1]!, - true, - ), + rule.between(expectedDates[0]!, expectedDates[expectedDates.length - 1]!, true), expectedDates, ); assertDatesEqual( - rule.between( - expectedDates[0]!, - expectedDates[expectedDates.length - 1]!, - false, - ), + rule.between(expectedDates[0]!, expectedDates[expectedDates.length - 1]!, false), expectedDates.slice(1, expectedDates.length - 1), ); } @@ -200,11 +182,7 @@ export const testRecurring = (( }) as TestRecurring; testRecurring.only = (...args) => { - testRecurring.apply(it, [...args, it.only] as unknown as [ - string, - unknown, - Date | Date[], - ]); + testRecurring.apply(it, [...args, it.only] as unknown as [string, unknown, Date | Date[]]); }; testRecurring.skip = (...args) => { @@ -212,10 +190,6 @@ testRecurring.skip = (...args) => { it.skip(description, () => {}); }; -export function expectedDate( - startDate: Date, - _currentLocalDate: Date, - targetZone: string, -): Date { +export function expectedDate(startDate: Date, _currentLocalDate: Date, targetZone: string): Date { return dateInTimeZone(startDate, targetZone); } diff --git a/test/nlp.test.ts b/test/nlp.test.ts index ddee9a25..7931748a 100644 --- a/test/nlp.test.ts +++ b/test/nlp.test.ts @@ -1,14 +1,11 @@ import { datetime, RRule } from '../src'; import type { DateFormatter } from '../src/nlp/totext'; -import { optionsToString } from '../src/optionstostring'; +import { optionsToString } from '../src/parse/stringify'; const texts = [ ['Every day', 'RRULE:FREQ=DAILY'], ['Every day at 10, 12 and 17', 'RRULE:FREQ=DAILY;BYHOUR=10,12,17'], - [ - 'Every week on Sunday at 10, 12 and 17', - 'RRULE:FREQ=WEEKLY;BYDAY=SU;BYHOUR=10,12,17', - ], + ['Every week on Sunday at 10, 12 and 17', 'RRULE:FREQ=WEEKLY;BYDAY=SU;BYHOUR=10,12,17'], ['Every week', 'RRULE:FREQ=WEEKLY'], ['Every hour', 'RRULE:FREQ=HOURLY'], ['Every 4 hours', 'RRULE:INTERVAL=4;FREQ=HOURLY'], @@ -52,9 +49,7 @@ describe('NLP', () => { toTexts.forEach((item) => { const text = item[0]; const str = item[1]; - expect(RRule.fromString(str).toText().toLowerCase()).toBe( - text.toLowerCase(), - ); + expect(RRule.fromString(str).toText().toLowerCase()).toBe(text.toLowerCase()); }); }); @@ -85,15 +80,7 @@ describe('NLP', () => { it('shows correct text for every day', () => { const options = { freq: RRule.WEEKLY, - byweekday: [ - RRule.MO, - RRule.TU, - RRule.WE, - RRule.TH, - RRule.FR, - RRule.SA, - RRule.SU, - ], + byweekday: [RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR, RRule.SA, RRule.SU], }; const rule = new RRule(options); expect(rule.toText()).toBe('every day'); @@ -126,11 +113,8 @@ describe('NLP', () => { until: datetime(2012, 11, 10), }); - const dateFormatter: DateFormatter = (year, month, day) => - `${day}. ${month}, ${year}`; + const dateFormatter: DateFormatter = (year, month, day) => `${day}. ${month}, ${year}`; - expect(rrule.toText(undefined, undefined, dateFormatter)).toBe( - 'every week until 10. November, 2012', - ); + expect(rrule.toText(undefined, undefined, dateFormatter)).toBe('every week until 10. November, 2012'); }); }); diff --git a/test/optionstostring.test.ts b/test/optionstostring.test.ts index 5c92c93b..50a7b458 100644 --- a/test/optionstostring.test.ts +++ b/test/optionstostring.test.ts @@ -1,14 +1,11 @@ import type { Options } from '../src'; import { datetime, RRule } from '../src'; -import { optionsToString } from '../src/optionstostring'; +import { optionsToString } from '../src/parse/stringify'; describe('optionsToString', () => { it('serializes valid single lines of rrules', () => { const expectations: [Partial, string][] = [ - [ - { freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }, - 'RRULE:FREQ=WEEKLY;UNTIL=20100101T000000Z', - ], + [{ freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }, 'RRULE:FREQ=WEEKLY;UNTIL=20100101T000000Z'], [ { dtstart: datetime(1997, 9, 2, 9, 0, 0), diff --git a/test/parseoptions.test.ts b/test/parseoptions.test.ts index bf0ae15b..ed88148b 100644 --- a/test/parseoptions.test.ts +++ b/test/parseoptions.test.ts @@ -1,5 +1,5 @@ import { RRule } from '../src'; -import { parseOptions } from '../src/parseoptions'; +import { parseOptions } from '../src/parse/options'; describe('TZID', () => { it('leaves null when null', () => { diff --git a/test/parsestring.test.ts b/test/parsestring.test.ts index 3d91841d..0be6fb69 100644 --- a/test/parsestring.test.ts +++ b/test/parsestring.test.ts @@ -1,19 +1,13 @@ import { datetime, Frequency, type Options, RRule } from '../src'; -import { parseString } from '../src/parsestring'; +import { parseString } from '../src/parse/string'; describe('parseString', () => { it('parses valid single lines of rrules', () => { const expectations: [string, Partial][] = [ - [ - 'FREQ=WEEKLY;UNTIL=20100101T000000Z', - { freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }, - ], + ['FREQ=WEEKLY;UNTIL=20100101T000000Z', { freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }], // Parse also `date` but return `date-time` - [ - 'FREQ=WEEKLY;UNTIL=20100101', - { freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }, - ], + ['FREQ=WEEKLY;UNTIL=20100101', { freq: RRule.WEEKLY, until: datetime(2010, 1, 1, 0, 0, 0) }], [ 'DTSTART;TZID=America/New_York:19970902T090000', { diff --git a/test/rrule.test.ts b/test/rrule.test.ts index ef8e0bbb..e72e3e3f 100644 --- a/test/rrule.test.ts +++ b/test/rrule.test.ts @@ -1,12 +1,6 @@ import { reset as resetMockDate, set as setMockDate } from 'mockdate'; import { Frequency, RRule, rrulestr } from '../src'; -import { - datetime, - expectedDate, - parse, - TEST_CTX, - testRecurring, -} from './lib/utils'; +import { datetime, expectedDate, parse, TEST_CTX, testRecurring } from './lib/utils'; describe('RRule', () => { beforeAll(() => { @@ -139,11 +133,7 @@ describe('RRule', () => { method: 'between', args: [parse('19970902T090000'), parse('19970906T090000')], }, - [ - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 5, 9, 0), - ], + [datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 5, 9, 0)], ); testRecurring( @@ -193,11 +183,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1998, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0)], ); testRecurring( @@ -208,11 +194,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - datetime(2001, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0), datetime(2001, 9, 2, 9, 0)], ); testRecurring( @@ -223,11 +205,7 @@ describe('RRule', () => { interval: 100, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(2097, 9, 2, 9, 0), - datetime(2197, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(2097, 9, 2, 9, 0), datetime(2197, 9, 2, 9, 0)], ); testRecurring( @@ -238,11 +216,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 2, 9, 0), - datetime(1998, 3, 2, 9, 0), - datetime(1999, 1, 2, 9, 0), - ], + [datetime(1998, 1, 2, 9, 0), datetime(1998, 3, 2, 9, 0), datetime(1999, 1, 2, 9, 0)], ); testRecurring( @@ -253,11 +227,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 9, 0), - datetime(1997, 10, 1, 9, 0), - datetime(1997, 10, 3, 9, 0), - ], + [datetime(1997, 9, 3, 9, 0), datetime(1997, 10, 1, 9, 0), datetime(1997, 10, 3, 9, 0)], ); testRecurring( @@ -269,11 +239,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 9, 0), - datetime(1998, 1, 7, 9, 0), - datetime(1998, 3, 5, 9, 0), - ], + [datetime(1998, 1, 5, 9, 0), datetime(1998, 1, 7, 9, 0), datetime(1998, 3, 5, 9, 0)], ); testRecurring( @@ -284,11 +250,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -299,11 +261,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 25, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 12, 31, 9, 0), - ], + [datetime(1997, 12, 25, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 12, 31, 9, 0)], ); testRecurring( @@ -314,11 +272,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(13), RRule.TH.nth(-13)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 10, 2, 9, 0), - datetime(1998, 3, 31, 9, 0), - datetime(1998, 10, 8, 9, 0), - ], + [datetime(1997, 10, 2, 9, 0), datetime(1998, 3, 31, 9, 0), datetime(1998, 10, 8, 9, 0)], ); testRecurring( @@ -330,11 +284,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -346,11 +296,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 29, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 29, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -362,11 +308,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(3), RRule.TH.nth(-3)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 15, 9, 0), - datetime(1998, 1, 20, 9, 0), - datetime(1998, 3, 12, 9, 0), - ], + [datetime(1998, 1, 15, 9, 0), datetime(1998, 1, 20, 9, 0), datetime(1998, 3, 12, 9, 0)], ); testRecurring( @@ -378,11 +320,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 2, 3, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 2, 3, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -395,11 +333,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 3, 3, 9, 0), - datetime(2001, 3, 1, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 3, 3, 9, 0), datetime(2001, 3, 1, 9, 0)], ); testRecurring( @@ -476,11 +410,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 9, 0), - datetime(1998, 5, 12, 9, 0), - datetime(1998, 5, 13, 9, 0), - ], + [datetime(1998, 5, 11, 9, 0), datetime(1998, 5, 12, 9, 0), datetime(1998, 5, 13, 9, 0)], ); testRecurring( @@ -494,11 +424,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 9, 0), - datetime(1999, 1, 4, 9, 0), - datetime(2000, 1, 3, 9, 0), - ], + [datetime(1997, 12, 29, 9, 0), datetime(1999, 1, 4, 9, 0), datetime(2000, 1, 3, 9, 0)], ); testRecurring( @@ -512,11 +438,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1998, 12, 27, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1998, 12, 27, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -528,22 +450,14 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1999, 1, 3, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1999, 1, 3, 9, 0), datetime(2000, 1, 2, 9, 0)], ); - testRecurring( - 'testYearlyByEaster', - new RRule({ count: 3, byeaster: 0, dtstart: parse('19970902T090000') }), - [ - datetime(1998, 4, 12, 9, 0), - datetime(1999, 4, 4, 9, 0), - datetime(2000, 4, 23, 9, 0), - ], - ); + testRecurring('testYearlyByEaster', new RRule({ count: 3, byeaster: 0, dtstart: parse('19970902T090000') }), [ + datetime(1998, 4, 12, 9, 0), + datetime(1999, 4, 4, 9, 0), + datetime(2000, 4, 23, 9, 0), + ]); testRecurring( 'testYearlyByEasterPos', @@ -553,11 +467,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 9, 0), - datetime(1999, 4, 5, 9, 0), - datetime(2000, 4, 24, 9, 0), - ], + [datetime(1998, 4, 13, 9, 0), datetime(1999, 4, 5, 9, 0), datetime(2000, 4, 24, 9, 0)], ); testRecurring( @@ -568,11 +478,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 9, 0), - datetime(1999, 4, 3, 9, 0), - datetime(2000, 4, 22, 9, 0), - ], + [datetime(1998, 4, 11, 9, 0), datetime(1999, 4, 3, 9, 0), datetime(2000, 4, 22, 9, 0)], ); testRecurring( @@ -584,11 +490,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 9, 0), - datetime(2004, 12, 27, 9, 0), - datetime(2009, 12, 28, 9, 0), - ], + [datetime(1998, 12, 28, 9, 0), datetime(2004, 12, 27, 9, 0), datetime(2009, 12, 28, 9, 0)], ); testRecurring( @@ -599,11 +501,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1998, 9, 2, 6, 0), - datetime(1998, 9, 2, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1998, 9, 2, 6, 0), datetime(1998, 9, 2, 18, 0)], ); testRecurring( @@ -614,11 +512,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1998, 9, 2, 9, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1998, 9, 2, 9, 6)], ); testRecurring( @@ -629,11 +523,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1998, 9, 2, 9, 0, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1998, 9, 2, 9, 0, 6)], ); testRecurring( @@ -645,11 +535,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1998, 9, 2, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1998, 9, 2, 6, 6)], ); testRecurring( @@ -661,11 +547,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1998, 9, 2, 6, 0, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1998, 9, 2, 6, 0, 6)], ); testRecurring( @@ -677,11 +559,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -694,11 +572,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -711,11 +585,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 11, 15, 18, 0), - datetime(1998, 2, 15, 6, 0), - datetime(1998, 11, 15, 18, 0), - ], + [datetime(1997, 11, 15, 18, 0), datetime(1998, 2, 15, 6, 0), datetime(1998, 11, 15, 18, 0)], ); testRecurring( @@ -751,11 +621,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 10, 2, 9, 0), - datetime(1997, 11, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 10, 2, 9, 0), datetime(1997, 11, 2, 9, 0)], ); testRecurring( @@ -766,11 +632,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 11, 2, 9, 0), - datetime(1998, 1, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 11, 2, 9, 0), datetime(1998, 1, 2, 9, 0)], ); testRecurring( @@ -781,11 +643,7 @@ describe('RRule', () => { interval: 18, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1999, 3, 2, 9, 0), - datetime(2000, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1999, 3, 2, 9, 0), datetime(2000, 9, 2, 9, 0)], ); testRecurring( @@ -796,11 +654,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 2, 9, 0), - datetime(1998, 3, 2, 9, 0), - datetime(1999, 1, 2, 9, 0), - ], + [datetime(1998, 1, 2, 9, 0), datetime(1998, 3, 2, 9, 0), datetime(1999, 1, 2, 9, 0)], ); testRecurring( @@ -811,11 +665,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 9, 0), - datetime(1997, 10, 1, 9, 0), - datetime(1997, 10, 3, 9, 0), - ], + [datetime(1997, 9, 3, 9, 0), datetime(1997, 10, 1, 9, 0), datetime(1997, 10, 3, 9, 0)], ); testRecurring( @@ -827,11 +677,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 9, 0), - datetime(1998, 1, 7, 9, 0), - datetime(1998, 3, 5, 9, 0), - ], + [datetime(1998, 1, 5, 9, 0), datetime(1998, 1, 7, 9, 0), datetime(1998, 3, 5, 9, 0)], ); testRecurring( @@ -842,11 +688,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -857,11 +699,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 25, 9, 0), - datetime(1997, 10, 7, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 25, 9, 0), datetime(1997, 10, 7, 9, 0)], ); testRecurring( @@ -872,11 +710,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(3), RRule.TH.nth(-3)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 11, 9, 0), - datetime(1997, 9, 16, 9, 0), - datetime(1997, 10, 16, 9, 0), - ], + [datetime(1997, 9, 11, 9, 0), datetime(1997, 9, 16, 9, 0), datetime(1997, 10, 16, 9, 0)], ); testRecurring( @@ -888,11 +722,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -904,11 +734,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 29, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 29, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -920,11 +746,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(3), RRule.TH.nth(-3)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 15, 9, 0), - datetime(1998, 1, 20, 9, 0), - datetime(1998, 3, 12, 9, 0), - ], + [datetime(1998, 1, 15, 9, 0), datetime(1998, 1, 20, 9, 0), datetime(1998, 3, 12, 9, 0)], ); testRecurring( @@ -936,11 +758,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 2, 3, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 2, 3, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -953,11 +771,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 3, 3, 9, 0), - datetime(2001, 3, 1, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 3, 3, 9, 0), datetime(2001, 3, 1, 9, 0)], ); testRecurring( @@ -1034,11 +848,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 9, 0), - datetime(1998, 5, 12, 9, 0), - datetime(1998, 5, 13, 9, 0), - ], + [datetime(1998, 5, 11, 9, 0), datetime(1998, 5, 12, 9, 0), datetime(1998, 5, 13, 9, 0)], ); testRecurring( @@ -1052,11 +862,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 9, 0), - datetime(1999, 1, 4, 9, 0), - datetime(2000, 1, 3, 9, 0), - ], + [datetime(1997, 12, 29, 9, 0), datetime(1999, 1, 4, 9, 0), datetime(2000, 1, 3, 9, 0)], ); testRecurring( @@ -1070,11 +876,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1998, 12, 27, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1998, 12, 27, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -1086,11 +888,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1999, 1, 3, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1999, 1, 3, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -1102,11 +900,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 9, 0), - datetime(2004, 12, 27, 9, 0), - datetime(2009, 12, 28, 9, 0), - ], + [datetime(1998, 12, 28, 9, 0), datetime(2004, 12, 27, 9, 0), datetime(2009, 12, 28, 9, 0)], ); testRecurring( @@ -1117,11 +911,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 9, 0), - datetime(1999, 4, 4, 9, 0), - datetime(2000, 4, 23, 9, 0), - ], + [datetime(1998, 4, 12, 9, 0), datetime(1999, 4, 4, 9, 0), datetime(2000, 4, 23, 9, 0)], ); testRecurring( @@ -1132,11 +922,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 9, 0), - datetime(1999, 4, 5, 9, 0), - datetime(2000, 4, 24, 9, 0), - ], + [datetime(1998, 4, 13, 9, 0), datetime(1999, 4, 5, 9, 0), datetime(2000, 4, 24, 9, 0)], ); testRecurring( @@ -1147,11 +933,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 9, 0), - datetime(1999, 4, 3, 9, 0), - datetime(2000, 4, 22, 9, 0), - ], + [datetime(1998, 4, 11, 9, 0), datetime(1999, 4, 3, 9, 0), datetime(2000, 4, 22, 9, 0)], ); testRecurring( @@ -1162,11 +944,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 10, 2, 6, 0), - datetime(1997, 10, 2, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 10, 2, 6, 0), datetime(1997, 10, 2, 18, 0)], ); testRecurring( @@ -1177,11 +955,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1997, 10, 2, 9, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1997, 10, 2, 9, 6)], ); testRecurring( @@ -1192,11 +966,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 10, 2, 9, 0, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 10, 2, 9, 0, 6)], ); testRecurring( @@ -1208,11 +978,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1997, 10, 2, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1997, 10, 2, 6, 6)], ); testRecurring( @@ -1224,11 +990,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 10, 2, 6, 0, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 10, 2, 6, 0, 6)], ); testRecurring( @@ -1240,11 +1002,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -1257,11 +1015,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -1274,11 +1028,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 13, 18, 0), - datetime(1997, 9, 17, 6, 0), - datetime(1997, 10, 13, 18, 0), - ], + [datetime(1997, 9, 13, 18, 0), datetime(1997, 9, 17, 6, 0), datetime(1997, 10, 13, 18, 0)], ); testRecurring( @@ -1320,11 +1070,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -1335,11 +1081,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 16, 9, 0), - datetime(1997, 9, 30, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 16, 9, 0), datetime(1997, 9, 30, 9, 0)], ); testRecurring( @@ -1350,11 +1092,7 @@ describe('RRule', () => { interval: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 1, 20, 9, 0), - datetime(1998, 6, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1998, 1, 20, 9, 0), datetime(1998, 6, 9, 9, 0)], ); testRecurring( @@ -1365,11 +1103,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 13, 9, 0), - datetime(1998, 1, 20, 9, 0), - ], + [datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 13, 9, 0), datetime(1998, 1, 20, 9, 0)], ); testRecurring( @@ -1380,11 +1114,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 9, 0), - datetime(1997, 10, 1, 9, 0), - datetime(1997, 10, 3, 9, 0), - ], + [datetime(1997, 9, 3, 9, 0), datetime(1997, 10, 1, 9, 0), datetime(1997, 10, 3, 9, 0)], ); testRecurring( @@ -1396,11 +1126,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 9, 0), - datetime(1998, 1, 7, 9, 0), - datetime(1998, 3, 5, 9, 0), - ], + [datetime(1998, 1, 5, 9, 0), datetime(1998, 1, 7, 9, 0), datetime(1998, 3, 5, 9, 0)], ); testRecurring( @@ -1411,11 +1137,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -1426,11 +1148,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -1445,11 +1163,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -1461,11 +1175,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -1477,11 +1187,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 2, 3, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 2, 3, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -1494,11 +1200,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 3, 3, 9, 0), - datetime(2001, 3, 1, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 3, 3, 9, 0), datetime(2001, 3, 1, 9, 0)], ); testRecurring( @@ -1542,12 +1244,7 @@ describe('RRule', () => { byyearday: [1, 100, 200, 365], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 7, 19, 9, 0), - datetime(1999, 1, 1, 9, 0), - datetime(1999, 7, 19, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 7, 19, 9, 0), datetime(1999, 1, 1, 9, 0), datetime(1999, 7, 19, 9, 0)], ); testRecurring( @@ -1559,12 +1256,7 @@ describe('RRule', () => { byyearday: [-365, -266, -166, -1], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 7, 19, 9, 0), - datetime(1999, 1, 1, 9, 0), - datetime(1999, 7, 19, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 7, 19, 9, 0), datetime(1999, 1, 1, 9, 0), datetime(1999, 7, 19, 9, 0)], ); testRecurring( @@ -1575,11 +1267,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 9, 0), - datetime(1998, 5, 12, 9, 0), - datetime(1998, 5, 13, 9, 0), - ], + [datetime(1998, 5, 11, 9, 0), datetime(1998, 5, 12, 9, 0), datetime(1998, 5, 13, 9, 0)], ); testRecurring( @@ -1593,11 +1281,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 9, 0), - datetime(1999, 1, 4, 9, 0), - datetime(2000, 1, 3, 9, 0), - ], + [datetime(1997, 12, 29, 9, 0), datetime(1999, 1, 4, 9, 0), datetime(2000, 1, 3, 9, 0)], ); testRecurring( @@ -1611,11 +1295,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1998, 12, 27, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1998, 12, 27, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -1627,11 +1307,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1999, 1, 3, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1999, 1, 3, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -1643,11 +1319,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 9, 0), - datetime(2004, 12, 27, 9, 0), - datetime(2009, 12, 28, 9, 0), - ], + [datetime(1998, 12, 28, 9, 0), datetime(2004, 12, 27, 9, 0), datetime(2009, 12, 28, 9, 0)], ); testRecurring( @@ -1658,11 +1330,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 9, 0), - datetime(1999, 4, 4, 9, 0), - datetime(2000, 4, 23, 9, 0), - ], + [datetime(1998, 4, 12, 9, 0), datetime(1999, 4, 4, 9, 0), datetime(2000, 4, 23, 9, 0)], ); testRecurring( @@ -1673,11 +1341,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 9, 0), - datetime(1999, 4, 5, 9, 0), - datetime(2000, 4, 24, 9, 0), - ], + [datetime(1998, 4, 13, 9, 0), datetime(1999, 4, 5, 9, 0), datetime(2000, 4, 24, 9, 0)], ); testRecurring( @@ -1688,11 +1352,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 9, 0), - datetime(1999, 4, 3, 9, 0), - datetime(2000, 4, 22, 9, 0), - ], + [datetime(1998, 4, 11, 9, 0), datetime(1999, 4, 3, 9, 0), datetime(2000, 4, 22, 9, 0)], ); testRecurring( @@ -1703,11 +1363,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 9, 9, 6, 0), - datetime(1997, 9, 9, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 9, 9, 6, 0), datetime(1997, 9, 9, 18, 0)], ); testRecurring( @@ -1718,11 +1374,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1997, 9, 9, 9, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1997, 9, 9, 9, 6)], ); testRecurring( @@ -1733,11 +1385,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 9, 9, 9, 0, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 9, 9, 9, 0, 6)], ); testRecurring( @@ -1749,11 +1397,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1997, 9, 9, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1997, 9, 9, 6, 6)], ); testRecurring( @@ -1765,11 +1409,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 9, 9, 6, 0, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 9, 9, 6, 0, 6)], ); testRecurring( @@ -1781,11 +1421,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -1798,11 +1434,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -1815,11 +1447,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 9, 4, 6, 0), - datetime(1997, 9, 9, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 9, 4, 6, 0), datetime(1997, 9, 9, 18, 0)], ); testRecurring( @@ -1829,11 +1457,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0)], ); testRecurring( @@ -1844,11 +1468,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 6, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 6, 9, 0)], ); testRecurring( @@ -1859,11 +1479,7 @@ describe('RRule', () => { interval: 92, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 12, 3, 9, 0), - datetime(1998, 3, 5, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 12, 3, 9, 0), datetime(1998, 3, 5, 9, 0)], ); testRecurring( @@ -1874,11 +1490,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 2, 9, 0), - datetime(1998, 1, 3, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 2, 9, 0), datetime(1998, 1, 3, 9, 0)], ); testRecurring( @@ -1889,11 +1501,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 9, 0), - datetime(1997, 10, 1, 9, 0), - datetime(1997, 10, 3, 9, 0), - ], + [datetime(1997, 9, 3, 9, 0), datetime(1997, 10, 1, 9, 0), datetime(1997, 10, 3, 9, 0)], ); testRecurring( @@ -1905,11 +1513,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 9, 0), - datetime(1998, 1, 7, 9, 0), - datetime(1998, 3, 5, 9, 0), - ], + [datetime(1998, 1, 5, 9, 0), datetime(1998, 1, 7, 9, 0), datetime(1998, 3, 5, 9, 0)], ); testRecurring( @@ -1920,11 +1524,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -1935,11 +1535,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -1951,11 +1547,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -1967,11 +1559,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 1, 8, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 1, 8, 9, 0)], ); testRecurring( @@ -1983,11 +1571,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 2, 3, 9, 0), - datetime(1998, 3, 3, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 2, 3, 9, 0), datetime(1998, 3, 3, 9, 0)], ); testRecurring( @@ -2000,11 +1584,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 3, 3, 9, 0), - datetime(2001, 3, 1, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 3, 3, 9, 0), datetime(2001, 3, 1, 9, 0)], ); testRecurring( @@ -2048,12 +1628,7 @@ describe('RRule', () => { byyearday: [1, 100, 200, 365], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 7, 19, 9, 0), - datetime(1999, 1, 1, 9, 0), - datetime(1999, 7, 19, 9, 0), - ], + [datetime(1998, 1, 1, 9, 0), datetime(1998, 7, 19, 9, 0), datetime(1999, 1, 1, 9, 0), datetime(1999, 7, 19, 9, 0)], ); testRecurring( @@ -2061,16 +1636,11 @@ describe('RRule', () => { new RRule({ freq: RRule.DAILY, count: 4, - bymonth: [1, 7], - byyearday: [-365, -266, -166, -1], - dtstart: parse('19970902T090000'), - }), - [ - datetime(1998, 1, 1, 9, 0), - datetime(1998, 7, 19, 9, 0), - datetime(1999, 1, 1, 9, 0), - datetime(1999, 7, 19, 9, 0), - ], + bymonth: [1, 7], + byyearday: [-365, -266, -166, -1], + dtstart: parse('19970902T090000'), + }), + [datetime(1998, 1, 1, 9, 0), datetime(1998, 7, 19, 9, 0), datetime(1999, 1, 1, 9, 0), datetime(1999, 7, 19, 9, 0)], ); testRecurring( @@ -2081,11 +1651,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 9, 0), - datetime(1998, 5, 12, 9, 0), - datetime(1998, 5, 13, 9, 0), - ], + [datetime(1998, 5, 11, 9, 0), datetime(1998, 5, 12, 9, 0), datetime(1998, 5, 13, 9, 0)], ); testRecurring( @@ -2099,11 +1665,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 9, 0), - datetime(1999, 1, 4, 9, 0), - datetime(2000, 1, 3, 9, 0), - ], + [datetime(1997, 12, 29, 9, 0), datetime(1999, 1, 4, 9, 0), datetime(2000, 1, 3, 9, 0)], ); testRecurring( @@ -2117,11 +1679,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1998, 12, 27, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1998, 12, 27, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -2133,11 +1691,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 9, 0), - datetime(1999, 1, 3, 9, 0), - datetime(2000, 1, 2, 9, 0), - ], + [datetime(1997, 12, 28, 9, 0), datetime(1999, 1, 3, 9, 0), datetime(2000, 1, 2, 9, 0)], ); testRecurring( @@ -2149,11 +1703,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 9, 0), - datetime(2004, 12, 27, 9, 0), - datetime(2009, 12, 28, 9, 0), - ], + [datetime(1998, 12, 28, 9, 0), datetime(2004, 12, 27, 9, 0), datetime(2009, 12, 28, 9, 0)], ); testRecurring( @@ -2164,11 +1714,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 9, 0), - datetime(1999, 4, 4, 9, 0), - datetime(2000, 4, 23, 9, 0), - ], + [datetime(1998, 4, 12, 9, 0), datetime(1999, 4, 4, 9, 0), datetime(2000, 4, 23, 9, 0)], ); testRecurring( @@ -2179,11 +1725,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 9, 0), - datetime(1999, 4, 5, 9, 0), - datetime(2000, 4, 24, 9, 0), - ], + [datetime(1998, 4, 13, 9, 0), datetime(1999, 4, 5, 9, 0), datetime(2000, 4, 24, 9, 0)], ); testRecurring( @@ -2194,11 +1736,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 9, 0), - datetime(1999, 4, 3, 9, 0), - datetime(2000, 4, 22, 9, 0), - ], + [datetime(1998, 4, 11, 9, 0), datetime(1999, 4, 3, 9, 0), datetime(2000, 4, 22, 9, 0)], ); testRecurring( @@ -2209,11 +1747,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 9, 3, 6, 0), - datetime(1997, 9, 3, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 9, 3, 6, 0), datetime(1997, 9, 3, 18, 0)], ); testRecurring( @@ -2224,11 +1758,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1997, 9, 3, 9, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1997, 9, 3, 9, 6)], ); testRecurring( @@ -2239,11 +1769,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 9, 3, 9, 0, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 9, 3, 9, 0, 6)], ); testRecurring( @@ -2255,11 +1781,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1997, 9, 3, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1997, 9, 3, 6, 6)], ); testRecurring( @@ -2271,11 +1793,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 9, 3, 6, 0, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 9, 3, 6, 0, 6)], ); testRecurring( @@ -2287,11 +1805,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -2304,11 +1818,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -2321,11 +1831,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 15), - datetime(1997, 9, 3, 6, 45), - datetime(1997, 9, 3, 18, 15), - ], + [datetime(1997, 9, 2, 18, 15), datetime(1997, 9, 3, 6, 45), datetime(1997, 9, 3, 18, 15)], ); testRecurring( @@ -2335,11 +1841,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 10, 0), - datetime(1997, 9, 2, 11, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 10, 0), datetime(1997, 9, 2, 11, 0)], ); testRecurring( @@ -2350,11 +1852,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 11, 0), - datetime(1997, 9, 2, 13, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 11, 0), datetime(1997, 9, 2, 13, 0)], ); testRecurring( @@ -2365,11 +1863,7 @@ describe('RRule', () => { interval: 769, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 10, 4, 10, 0), - datetime(1997, 11, 5, 11, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 10, 4, 10, 0), datetime(1997, 11, 5, 11, 0)], ); testRecurring( @@ -2380,11 +1874,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 1, 0), - datetime(1998, 1, 1, 2, 0), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 1, 0), datetime(1998, 1, 1, 2, 0)], ); testRecurring( @@ -2395,11 +1885,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 0, 0), - datetime(1997, 9, 3, 1, 0), - datetime(1997, 9, 3, 2, 0), - ], + [datetime(1997, 9, 3, 0, 0), datetime(1997, 9, 3, 1, 0), datetime(1997, 9, 3, 2, 0)], ); testRecurring( @@ -2411,11 +1897,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 0, 0), - datetime(1998, 1, 5, 1, 0), - datetime(1998, 1, 5, 2, 0), - ], + [datetime(1998, 1, 5, 0, 0), datetime(1998, 1, 5, 1, 0), datetime(1998, 1, 5, 2, 0)], ); testRecurring( @@ -2426,11 +1908,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 10, 0), - datetime(1997, 9, 2, 11, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 10, 0), datetime(1997, 9, 2, 11, 0)], ); testRecurring( @@ -2441,11 +1919,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 10, 0), - datetime(1997, 9, 2, 11, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 10, 0), datetime(1997, 9, 2, 11, 0)], ); testRecurring( @@ -2457,11 +1931,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 1, 0), - datetime(1998, 1, 1, 2, 0), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 1, 0), datetime(1998, 1, 1, 2, 0)], ); testRecurring( @@ -2473,11 +1943,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 1, 0), - datetime(1998, 1, 1, 2, 0), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 1, 0), datetime(1998, 1, 1, 2, 0)], ); testRecurring( @@ -2489,11 +1955,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 1, 0), - datetime(1998, 1, 1, 2, 0), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 1, 0), datetime(1998, 1, 1, 2, 0)], ); testRecurring( @@ -2506,11 +1968,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 1, 0), - datetime(1998, 1, 1, 2, 0), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 1, 0), datetime(1998, 1, 1, 2, 0)], ); testRecurring( @@ -2587,11 +2045,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 0, 0), - datetime(1998, 5, 11, 1, 0), - datetime(1998, 5, 11, 2, 0), - ], + [datetime(1998, 5, 11, 0, 0), datetime(1998, 5, 11, 1, 0), datetime(1998, 5, 11, 2, 0)], ); testRecurring( @@ -2603,11 +2057,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 0, 0), - datetime(1997, 12, 29, 1, 0), - datetime(1997, 12, 29, 2, 0), - ], + [datetime(1997, 12, 29, 0, 0), datetime(1997, 12, 29, 1, 0), datetime(1997, 12, 29, 2, 0)], ); testRecurring( @@ -2619,11 +2069,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0), - datetime(1997, 12, 28, 1, 0), - datetime(1997, 12, 28, 2, 0), - ], + [datetime(1997, 12, 28, 0, 0), datetime(1997, 12, 28, 1, 0), datetime(1997, 12, 28, 2, 0)], ); testRecurring( @@ -2635,11 +2081,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0), - datetime(1997, 12, 28, 1, 0), - datetime(1997, 12, 28, 2, 0), - ], + [datetime(1997, 12, 28, 0, 0), datetime(1997, 12, 28, 1, 0), datetime(1997, 12, 28, 2, 0)], ); testRecurring( @@ -2651,11 +2093,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 0, 0), - datetime(1998, 12, 28, 1, 0), - datetime(1998, 12, 28, 2, 0), - ], + [datetime(1998, 12, 28, 0, 0), datetime(1998, 12, 28, 1, 0), datetime(1998, 12, 28, 2, 0)], ); testRecurring.skip( @@ -2666,11 +2104,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 0, 0), - datetime(1998, 4, 12, 1, 0), - datetime(1998, 4, 12, 2, 0), - ], + [datetime(1998, 4, 12, 0, 0), datetime(1998, 4, 12, 1, 0), datetime(1998, 4, 12, 2, 0)], ); testRecurring.skip( @@ -2681,11 +2115,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 0, 0), - datetime(1998, 4, 13, 1, 0), - datetime(1998, 4, 13, 2, 0), - ], + [datetime(1998, 4, 13, 0, 0), datetime(1998, 4, 13, 1, 0), datetime(1998, 4, 13, 2, 0)], ); testRecurring.skip( @@ -2696,11 +2126,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 0, 0), - datetime(1998, 4, 11, 1, 0), - datetime(1998, 4, 11, 2, 0), - ], + [datetime(1998, 4, 11, 0, 0), datetime(1998, 4, 11, 1, 0), datetime(1998, 4, 11, 2, 0)], ); testRecurring( @@ -2711,11 +2137,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 9, 3, 6, 0), - datetime(1997, 9, 3, 18, 0), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 9, 3, 6, 0), datetime(1997, 9, 3, 18, 0)], ); testRecurring( @@ -2726,11 +2148,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1997, 9, 2, 10, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1997, 9, 2, 10, 6)], ); testRecurring( @@ -2741,11 +2159,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 9, 2, 10, 0, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 9, 2, 10, 0, 6)], ); testRecurring( @@ -2757,11 +2171,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1997, 9, 3, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1997, 9, 3, 6, 6)], ); testRecurring( @@ -2773,11 +2183,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 9, 3, 6, 0, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 9, 3, 6, 0, 6)], ); testRecurring( @@ -2789,11 +2195,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -2806,11 +2208,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -2823,11 +2221,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 15, 45), - datetime(1997, 9, 2, 9, 45, 15), - datetime(1997, 9, 2, 10, 15, 45), - ], + [datetime(1997, 9, 2, 9, 15, 45), datetime(1997, 9, 2, 9, 45, 15), datetime(1997, 9, 2, 10, 15, 45)], ); testRecurring( @@ -2837,11 +2231,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 9, 1), - datetime(1997, 9, 2, 9, 2), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 9, 1), datetime(1997, 9, 2, 9, 2)], ); testRecurring( @@ -2852,11 +2242,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 9, 2), - datetime(1997, 9, 2, 9, 4), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 9, 2), datetime(1997, 9, 2, 9, 4)], ); testRecurring( @@ -2867,11 +2253,7 @@ describe('RRule', () => { interval: 1501, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 10, 1), - datetime(1997, 9, 4, 11, 2), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 10, 1), datetime(1997, 9, 4, 11, 2)], ); testRecurring( @@ -2882,11 +2264,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 0, 1), - datetime(1998, 1, 1, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 0, 1), datetime(1998, 1, 1, 0, 2)], ); testRecurring( @@ -2897,11 +2275,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 0, 0), - datetime(1997, 9, 3, 0, 1), - datetime(1997, 9, 3, 0, 2), - ], + [datetime(1997, 9, 3, 0, 0), datetime(1997, 9, 3, 0, 1), datetime(1997, 9, 3, 0, 2)], ); testRecurring( @@ -2913,11 +2287,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 0, 0), - datetime(1998, 1, 5, 0, 1), - datetime(1998, 1, 5, 0, 2), - ], + [datetime(1998, 1, 5, 0, 0), datetime(1998, 1, 5, 0, 1), datetime(1998, 1, 5, 0, 2)], ); testRecurring( @@ -2928,11 +2298,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 9, 1), - datetime(1997, 9, 2, 9, 2), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 9, 1), datetime(1997, 9, 2, 9, 2)], ); testRecurring( @@ -2943,11 +2309,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 2, 9, 1), - datetime(1997, 9, 2, 9, 2), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 2, 9, 1), datetime(1997, 9, 2, 9, 2)], ); testRecurring( @@ -2959,11 +2321,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 0, 1), - datetime(1998, 1, 1, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 0, 1), datetime(1998, 1, 1, 0, 2)], ); testRecurring( @@ -2975,11 +2333,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 0, 1), - datetime(1998, 1, 1, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 0, 1), datetime(1998, 1, 1, 0, 2)], ); testRecurring( @@ -2991,11 +2345,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 0, 1), - datetime(1998, 1, 1, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 0, 1), datetime(1998, 1, 1, 0, 2)], ); testRecurring( @@ -3008,11 +2358,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0), - datetime(1998, 1, 1, 0, 1), - datetime(1998, 1, 1, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0), datetime(1998, 1, 1, 0, 1), datetime(1998, 1, 1, 0, 2)], ); testRecurring( @@ -3089,11 +2435,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 0, 0), - datetime(1998, 5, 11, 0, 1), - datetime(1998, 5, 11, 0, 2), - ], + [datetime(1998, 5, 11, 0, 0), datetime(1998, 5, 11, 0, 1), datetime(1998, 5, 11, 0, 2)], ); testRecurring( @@ -3105,11 +2447,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 0, 0), - datetime(1997, 12, 29, 0, 1), - datetime(1997, 12, 29, 0, 2), - ], + [datetime(1997, 12, 29, 0, 0), datetime(1997, 12, 29, 0, 1), datetime(1997, 12, 29, 0, 2)], ); testRecurring( @@ -3121,11 +2459,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0), - datetime(1997, 12, 28, 0, 1), - datetime(1997, 12, 28, 0, 2), - ], + [datetime(1997, 12, 28, 0, 0), datetime(1997, 12, 28, 0, 1), datetime(1997, 12, 28, 0, 2)], ); testRecurring( @@ -3137,11 +2471,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0), - datetime(1997, 12, 28, 0, 1), - datetime(1997, 12, 28, 0, 2), - ], + [datetime(1997, 12, 28, 0, 0), datetime(1997, 12, 28, 0, 1), datetime(1997, 12, 28, 0, 2)], ); testRecurring( @@ -3153,11 +2483,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 0, 0), - datetime(1998, 12, 28, 0, 1), - datetime(1998, 12, 28, 0, 2), - ], + [datetime(1998, 12, 28, 0, 0), datetime(1998, 12, 28, 0, 1), datetime(1998, 12, 28, 0, 2)], ); testRecurring.skip( @@ -3168,11 +2494,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 0, 0), - datetime(1998, 4, 12, 0, 1), - datetime(1998, 4, 12, 0, 2), - ], + [datetime(1998, 4, 12, 0, 0), datetime(1998, 4, 12, 0, 1), datetime(1998, 4, 12, 0, 2)], ); testRecurring.skip( @@ -3183,11 +2505,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 0, 0), - datetime(1998, 4, 13, 0, 1), - datetime(1998, 4, 13, 0, 2), - ], + [datetime(1998, 4, 13, 0, 0), datetime(1998, 4, 13, 0, 1), datetime(1998, 4, 13, 0, 2)], ); testRecurring.skip( @@ -3198,11 +2516,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 0, 0), - datetime(1998, 4, 11, 0, 1), - datetime(1998, 4, 11, 0, 2), - ], + [datetime(1998, 4, 11, 0, 0), datetime(1998, 4, 11, 0, 1), datetime(1998, 4, 11, 0, 2)], ); testRecurring( @@ -3213,11 +2527,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0), - datetime(1997, 9, 2, 18, 1), - datetime(1997, 9, 2, 18, 2), - ], + [datetime(1997, 9, 2, 18, 0), datetime(1997, 9, 2, 18, 1), datetime(1997, 9, 2, 18, 2)], ); testRecurring( @@ -3228,11 +2538,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6), - datetime(1997, 9, 2, 9, 18), - datetime(1997, 9, 2, 10, 6), - ], + [datetime(1997, 9, 2, 9, 6), datetime(1997, 9, 2, 9, 18), datetime(1997, 9, 2, 10, 6)], ); testRecurring( @@ -3243,11 +2549,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 9, 2, 9, 1, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 9, 2, 9, 1, 6)], ); testRecurring( @@ -3259,11 +2561,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6), - datetime(1997, 9, 2, 18, 18), - datetime(1997, 9, 3, 6, 6), - ], + [datetime(1997, 9, 2, 18, 6), datetime(1997, 9, 2, 18, 18), datetime(1997, 9, 3, 6, 6)], ); testRecurring( @@ -3275,11 +2573,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 9, 2, 18, 1, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 9, 2, 18, 1, 6)], ); testRecurring( @@ -3291,11 +2585,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -3308,11 +2598,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -3324,11 +2610,7 @@ describe('RRule', () => { bysetpos: [3, -3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 15), - datetime(1997, 9, 2, 9, 0, 45), - datetime(1997, 9, 2, 9, 1, 15), - ], + [datetime(1997, 9, 2, 9, 0, 15), datetime(1997, 9, 2, 9, 0, 45), datetime(1997, 9, 2, 9, 1, 15)], ); testRecurring( @@ -3338,11 +2620,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 0), - datetime(1997, 9, 2, 9, 0, 1), - datetime(1997, 9, 2, 9, 0, 2), - ], + [datetime(1997, 9, 2, 9, 0, 0), datetime(1997, 9, 2, 9, 0, 1), datetime(1997, 9, 2, 9, 0, 2)], ); testRecurring( @@ -3353,11 +2631,7 @@ describe('RRule', () => { interval: 2, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 0), - datetime(1997, 9, 2, 9, 0, 2), - datetime(1997, 9, 2, 9, 0, 4), - ], + [datetime(1997, 9, 2, 9, 0, 0), datetime(1997, 9, 2, 9, 0, 2), datetime(1997, 9, 2, 9, 0, 4)], ); testRecurring( @@ -3368,11 +2642,7 @@ describe('RRule', () => { interval: 90061, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 0), - datetime(1997, 9, 3, 10, 1, 1), - datetime(1997, 9, 4, 11, 2, 2), - ], + [datetime(1997, 9, 2, 9, 0, 0), datetime(1997, 9, 3, 10, 1, 1), datetime(1997, 9, 4, 11, 2, 2)], ); testRecurring( @@ -3383,11 +2653,7 @@ describe('RRule', () => { bymonth: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0, 0), - datetime(1998, 1, 1, 0, 0, 1), - datetime(1998, 1, 1, 0, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0, 0), datetime(1998, 1, 1, 0, 0, 1), datetime(1998, 1, 1, 0, 0, 2)], ); testRecurring( @@ -3398,11 +2664,7 @@ describe('RRule', () => { bymonthday: [1, 3], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 3, 0, 0, 0), - datetime(1997, 9, 3, 0, 0, 1), - datetime(1997, 9, 3, 0, 0, 2), - ], + [datetime(1997, 9, 3, 0, 0, 0), datetime(1997, 9, 3, 0, 0, 1), datetime(1997, 9, 3, 0, 0, 2)], ); testRecurring( @@ -3414,11 +2676,7 @@ describe('RRule', () => { bymonthday: [5, 7], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 5, 0, 0, 0), - datetime(1998, 1, 5, 0, 0, 1), - datetime(1998, 1, 5, 0, 0, 2), - ], + [datetime(1998, 1, 5, 0, 0, 0), datetime(1998, 1, 5, 0, 0, 1), datetime(1998, 1, 5, 0, 0, 2)], ); testRecurring( @@ -3429,11 +2687,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 0), - datetime(1997, 9, 2, 9, 0, 1), - datetime(1997, 9, 2, 9, 0, 2), - ], + [datetime(1997, 9, 2, 9, 0, 0), datetime(1997, 9, 2, 9, 0, 1), datetime(1997, 9, 2, 9, 0, 2)], ); testRecurring( @@ -3444,11 +2698,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 0), - datetime(1997, 9, 2, 9, 0, 1), - datetime(1997, 9, 2, 9, 0, 2), - ], + [datetime(1997, 9, 2, 9, 0, 0), datetime(1997, 9, 2, 9, 0, 1), datetime(1997, 9, 2, 9, 0, 2)], ); testRecurring( @@ -3460,11 +2710,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0, 0), - datetime(1998, 1, 1, 0, 0, 1), - datetime(1998, 1, 1, 0, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0, 0), datetime(1998, 1, 1, 0, 0, 1), datetime(1998, 1, 1, 0, 0, 2)], ); testRecurring( @@ -3476,11 +2722,7 @@ describe('RRule', () => { byweekday: [RRule.TU.nth(1), RRule.TH.nth(-1)], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0, 0), - datetime(1998, 1, 1, 0, 0, 1), - datetime(1998, 1, 1, 0, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0, 0), datetime(1998, 1, 1, 0, 0, 1), datetime(1998, 1, 1, 0, 0, 2)], ); testRecurring( @@ -3492,11 +2734,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0, 0), - datetime(1998, 1, 1, 0, 0, 1), - datetime(1998, 1, 1, 0, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0, 0), datetime(1998, 1, 1, 0, 0, 1), datetime(1998, 1, 1, 0, 0, 2)], ); testRecurring( @@ -3509,11 +2747,7 @@ describe('RRule', () => { byweekday: [RRule.TU, RRule.TH], dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 1, 1, 0, 0, 0), - datetime(1998, 1, 1, 0, 0, 1), - datetime(1998, 1, 1, 0, 0, 2), - ], + [datetime(1998, 1, 1, 0, 0, 0), datetime(1998, 1, 1, 0, 0, 1), datetime(1998, 1, 1, 0, 0, 2)], ); testRecurring( @@ -3590,11 +2824,7 @@ describe('RRule', () => { byweekno: 20, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 5, 11, 0, 0, 0), - datetime(1998, 5, 11, 0, 0, 1), - datetime(1998, 5, 11, 0, 0, 2), - ], + [datetime(1998, 5, 11, 0, 0, 0), datetime(1998, 5, 11, 0, 0, 1), datetime(1998, 5, 11, 0, 0, 2)], ); testRecurring( @@ -3606,11 +2836,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 29, 0, 0, 0), - datetime(1997, 12, 29, 0, 0, 1), - datetime(1997, 12, 29, 0, 0, 2), - ], + [datetime(1997, 12, 29, 0, 0, 0), datetime(1997, 12, 29, 0, 0, 1), datetime(1997, 12, 29, 0, 0, 2)], ); testRecurring( @@ -3622,11 +2848,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0, 0), - datetime(1997, 12, 28, 0, 0, 1), - datetime(1997, 12, 28, 0, 0, 2), - ], + [datetime(1997, 12, 28, 0, 0, 0), datetime(1997, 12, 28, 0, 0, 1), datetime(1997, 12, 28, 0, 0, 2)], ); testRecurring( @@ -3638,11 +2860,7 @@ describe('RRule', () => { byweekday: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 12, 28, 0, 0, 0), - datetime(1997, 12, 28, 0, 0, 1), - datetime(1997, 12, 28, 0, 0, 2), - ], + [datetime(1997, 12, 28, 0, 0, 0), datetime(1997, 12, 28, 0, 0, 1), datetime(1997, 12, 28, 0, 0, 2)], ); testRecurring( @@ -3654,11 +2872,7 @@ describe('RRule', () => { byweekday: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 12, 28, 0, 0, 0), - datetime(1998, 12, 28, 0, 0, 1), - datetime(1998, 12, 28, 0, 0, 2), - ], + [datetime(1998, 12, 28, 0, 0, 0), datetime(1998, 12, 28, 0, 0, 1), datetime(1998, 12, 28, 0, 0, 2)], ); testRecurring.skip( @@ -3669,11 +2883,7 @@ describe('RRule', () => { byeaster: 0, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 12, 0, 0, 0), - datetime(1998, 4, 12, 0, 0, 1), - datetime(1998, 4, 12, 0, 0, 2), - ], + [datetime(1998, 4, 12, 0, 0, 0), datetime(1998, 4, 12, 0, 0, 1), datetime(1998, 4, 12, 0, 0, 2)], ); testRecurring.skip( @@ -3684,11 +2894,7 @@ describe('RRule', () => { byeaster: 1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 13, 0, 0, 0), - datetime(1998, 4, 13, 0, 0, 1), - datetime(1998, 4, 13, 0, 0, 2), - ], + [datetime(1998, 4, 13, 0, 0, 0), datetime(1998, 4, 13, 0, 0, 1), datetime(1998, 4, 13, 0, 0, 2)], ); testRecurring.skip( @@ -3699,11 +2905,7 @@ describe('RRule', () => { byeaster: -1, dtstart: parse('19970902T090000'), }), - [ - datetime(1998, 4, 11, 0, 0, 0), - datetime(1998, 4, 11, 0, 0, 1), - datetime(1998, 4, 11, 0, 0, 2), - ], + [datetime(1998, 4, 11, 0, 0, 0), datetime(1998, 4, 11, 0, 0, 1), datetime(1998, 4, 11, 0, 0, 2)], ); testRecurring( @@ -3714,11 +2916,7 @@ describe('RRule', () => { byhour: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 0), - datetime(1997, 9, 2, 18, 0, 1), - datetime(1997, 9, 2, 18, 0, 2), - ], + [datetime(1997, 9, 2, 18, 0, 0), datetime(1997, 9, 2, 18, 0, 1), datetime(1997, 9, 2, 18, 0, 2)], ); testRecurring( @@ -3729,11 +2927,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 0), - datetime(1997, 9, 2, 9, 6, 1), - datetime(1997, 9, 2, 9, 6, 2), - ], + [datetime(1997, 9, 2, 9, 6, 0), datetime(1997, 9, 2, 9, 6, 1), datetime(1997, 9, 2, 9, 6, 2)], ); testRecurring( @@ -3744,11 +2938,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0, 6), - datetime(1997, 9, 2, 9, 0, 18), - datetime(1997, 9, 2, 9, 1, 6), - ], + [datetime(1997, 9, 2, 9, 0, 6), datetime(1997, 9, 2, 9, 0, 18), datetime(1997, 9, 2, 9, 1, 6)], ); testRecurring( @@ -3760,11 +2950,7 @@ describe('RRule', () => { byminute: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 0), - datetime(1997, 9, 2, 18, 6, 1), - datetime(1997, 9, 2, 18, 6, 2), - ], + [datetime(1997, 9, 2, 18, 6, 0), datetime(1997, 9, 2, 18, 6, 1), datetime(1997, 9, 2, 18, 6, 2)], ); testRecurring( @@ -3776,11 +2962,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 0, 6), - datetime(1997, 9, 2, 18, 0, 18), - datetime(1997, 9, 2, 18, 1, 6), - ], + [datetime(1997, 9, 2, 18, 0, 6), datetime(1997, 9, 2, 18, 0, 18), datetime(1997, 9, 2, 18, 1, 6)], ); testRecurring( @@ -3792,11 +2974,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 6, 6), - datetime(1997, 9, 2, 9, 6, 18), - datetime(1997, 9, 2, 9, 18, 6), - ], + [datetime(1997, 9, 2, 9, 6, 6), datetime(1997, 9, 2, 9, 6, 18), datetime(1997, 9, 2, 9, 18, 6)], ); testRecurring( @@ -3809,11 +2987,7 @@ describe('RRule', () => { bysecond: [6, 18], dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 18, 6, 6), - datetime(1997, 9, 2, 18, 6, 18), - datetime(1997, 9, 2, 18, 18, 6), - ], + [datetime(1997, 9, 2, 18, 6, 6), datetime(1997, 9, 2, 18, 6, 18), datetime(1997, 9, 2, 18, 18, 6)], ); testRecurring( @@ -3824,11 +2998,7 @@ describe('RRule', () => { dtstart: parse('19970902T090000'), until: parse('19970905T080000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0)], ); testRecurring( @@ -3839,11 +3009,7 @@ describe('RRule', () => { dtstart: parse('19970902T090000'), until: parse('19970904T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0)], ); testRecurring( @@ -3876,11 +3042,7 @@ describe('RRule', () => { dtstart: parse('19970902T090000'), until: datetime(1997, 9, 5), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0)], ); testRecurring( @@ -3893,11 +3055,7 @@ describe('RRule', () => { wkst: RRule.MO, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 7, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 7, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -3910,22 +3068,14 @@ describe('RRule', () => { wkst: RRule.SU, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 14, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 14, 9, 0), datetime(1997, 9, 16, 9, 0)], ); - testRecurring( - 'testDTStartIsDate', - new RRule({ freq: RRule.DAILY, count: 3, dtstart: datetime(1997, 9, 2) }), - [ - datetime(1997, 9, 2, 0, 0), - datetime(1997, 9, 3, 0, 0), - datetime(1997, 9, 4, 0, 0), - ], - ); + testRecurring('testDTStartIsDate', new RRule({ freq: RRule.DAILY, count: 3, dtstart: datetime(1997, 9, 2) }), [ + datetime(1997, 9, 2, 0, 0), + datetime(1997, 9, 3, 0, 0), + datetime(1997, 9, 4, 0, 0), + ]); testRecurring( 'testDTStartWithMicroseconds', @@ -3934,11 +3084,7 @@ describe('RRule', () => { count: 3, dtstart: parse('19970902T090000.5'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 3, 9, 0), - datetime(1997, 9, 4, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 3, 9, 0), datetime(1997, 9, 4, 9, 0)], ); testRecurring( @@ -3975,22 +3121,22 @@ describe('RRule', () => { ); it('testAfterBefore', () => { - ( - ['YEARLY', 'MONTHLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'] as const - ).forEach((freqStr: keyof typeof Frequency) => { - const date = new Date(1356991200001); - const rr = new RRule({ - freq: RRule[freqStr], - dtstart: date, - }); - - expect(date.getTime()).toBe(rr.options.dtstart.getTime()); - const res: Date = rr.before(rr.after(rr.options.dtstart)); - - let resTimestamp: number; - if (res != null) resTimestamp = res.getTime(); - expect(resTimestamp).toBe(rr.options.dtstart.getTime()); - }); + (['YEARLY', 'MONTHLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'] as const).forEach( + (freqStr: keyof typeof Frequency) => { + const date = new Date(1356991200001); + const rr = new RRule({ + freq: RRule[freqStr], + dtstart: date, + }); + + expect(date.getTime()).toBe(rr.options.dtstart.getTime()); + const res: Date = rr.before(rr.after(rr.options.dtstart)); + + let resTimestamp: number; + if (res != null) resTimestamp = res.getTime(); + expect(resTimestamp).toBe(rr.options.dtstart.getTime()); + }, + ); }); it('testConvertAndBack', () => { @@ -4001,15 +3147,7 @@ describe('RRule', () => { freq: RRule.MONTHLY, interval: 1, bysetpos: 17, - byweekday: [ - RRule.SU, - RRule.MO, - RRule.TU, - RRule.WE, - RRule.TH, - RRule.FR, - RRule.SA, - ], + byweekday: [RRule.SU, RRule.MO, RRule.TU, RRule.WE, RRule.TH, RRule.FR, RRule.SA], wkst: wkst, byhour: 11, byminute: 0, @@ -4044,9 +3182,7 @@ describe('RRule', () => { }); it('calculates daily recurrences correctly across DST boundaries', () => { - const rrule = RRule.fromString( - 'DTSTART=20181101T110000Z;UNTIL=20181106T110000Z;FREQ=DAILY', - ); + const rrule = RRule.fromString('DTSTART=20181101T110000Z;UNTIL=20181106T110000Z;FREQ=DAILY'); expect(rrule.all()).toEqual([ new Date('2018-11-01T11:00:00.000Z'), new Date('2018-11-02T11:00:00.000Z'), @@ -4058,9 +3194,7 @@ describe('RRule', () => { }); it('calculates weekly recurrences correctly across DST boundaries', () => { - const rrule = RRule.fromString( - 'DTSTART=20181031T180000Z\nRRULE:FREQ=WEEKLY;UNTIL=20181115T050000Z', - ); + const rrule = RRule.fromString('DTSTART=20181031T180000Z\nRRULE:FREQ=WEEKLY;UNTIL=20181115T050000Z'); expect(rrule.all()).toEqual([ new Date('2018-10-31T18:00:00.000Z'), new Date('2018-11-07T18:00:00.000Z'), @@ -4135,8 +3269,7 @@ describe('RRule', () => { }); it('generates around dst (#249)', () => { - const ruleString = - 'DTSTART:20181101T120000Z\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR;COUNT=4;WKST=SU'; + const ruleString = 'DTSTART:20181101T120000Z\nRRULE:FREQ=WEEKLY;INTERVAL=1;BYDAY=MO,WE,FR;COUNT=4;WKST=SU'; const rrule = RRule.fromString(ruleString); expect(rrule.all()).toEqual([ @@ -4220,12 +3353,8 @@ describe('RRule', () => { it('throws an error when dtstart is invalid', () => { const invalidDate = new Date(undefined); const validDate = datetime(2017, 1, 1); - expect(() => new RRule({ dtstart: invalidDate })).toThrow( - 'Invalid options: dtstart', - ); - expect(() => new RRule({ dtstart: validDate, until: invalidDate })).toThrow( - 'Invalid options: until', - ); + expect(() => new RRule({ dtstart: invalidDate })).toThrow('Invalid options: dtstart'); + expect(() => new RRule({ dtstart: validDate, until: invalidDate })).toThrow('Invalid options: until'); const rule = new RRule({ dtstart: datetime(2017, 1, 1), @@ -4233,17 +3362,9 @@ describe('RRule', () => { interval: 1, }); - expect(() => rule.after(invalidDate)).toThrow( - 'Invalid date passed in to RRule.after', - ); - expect(() => rule.before(invalidDate)).toThrow( - 'Invalid date passed in to RRule.before', - ); - expect(() => rule.between(invalidDate, validDate)).toThrow( - 'Invalid date passed in to RRule.between', - ); - expect(() => rule.between(validDate, invalidDate)).toThrow( - 'Invalid date passed in to RRule.between', - ); + expect(() => rule.after(invalidDate)).toThrow('Invalid date passed in to RRule.after'); + expect(() => rule.before(invalidDate)).toThrow('Invalid date passed in to RRule.before'); + expect(() => rule.between(invalidDate, validDate)).toThrow('Invalid date passed in to RRule.between'); + expect(() => rule.between(validDate, invalidDate)).toThrow('Invalid date passed in to RRule.between'); }); }); diff --git a/test/rruleset.test.ts b/test/rruleset.test.ts index 867eab13..c3f75334 100644 --- a/test/rruleset.test.ts +++ b/test/rruleset.test.ts @@ -1,12 +1,6 @@ import { reset as resetMockDate, set as setMockDate } from 'mockdate'; import { Frequency, RRule, RRuleSet, rrulestr } from '../src'; -import { - datetime, - expectedDate, - parse, - TEST_CTX, - testRecurring, -} from './lib/utils'; +import { datetime, expectedDate, parse, TEST_CTX, testRecurring } from './lib/utils'; describe('RRuleSet', () => { beforeAll(() => { @@ -47,11 +41,7 @@ describe('RRuleSet', () => { }), ); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)]); testRecurring('testSetDate', () => { const set = new RRuleSet(); @@ -67,11 +57,7 @@ describe('RRuleSet', () => { set.rdate(datetime(1997, 9, 4, 9)); set.rdate(datetime(1997, 9, 9, 9)); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)]); testRecurring('testSetExRule', () => { const set = new RRuleSet(); @@ -93,11 +79,7 @@ describe('RRuleSet', () => { }), ); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)]); testRecurring('testSetExDate', () => { const set = new RRuleSet(); @@ -114,11 +96,7 @@ describe('RRuleSet', () => { set.exdate(datetime(1997, 9, 11, 9)); set.exdate(datetime(1997, 9, 18, 9)); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)]); testRecurring('testSetExDateRevOrder', () => { const set = new RRuleSet(); @@ -134,11 +112,7 @@ describe('RRuleSet', () => { set.exdate(datetime(2004, 4, 10, 9, 0)); set.exdate(datetime(2004, 2, 10, 9, 0)); return set; - }, [ - datetime(2004, 1, 10, 9, 0), - datetime(2004, 3, 10, 9, 0), - datetime(2004, 5, 10, 9, 0), - ]); + }, [datetime(2004, 1, 10, 9, 0), datetime(2004, 3, 10, 9, 0), datetime(2004, 5, 10, 9, 0)]); testRecurring('testSetDateAndExDate', () => { const set = new RRuleSet(); @@ -153,11 +127,7 @@ describe('RRuleSet', () => { set.exdate(datetime(1997, 9, 11, 9)); set.exdate(datetime(1997, 9, 18, 9)); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)]); testRecurring('testSetDateAndExRule', () => { const set = new RRuleSet(); @@ -177,11 +147,7 @@ describe('RRuleSet', () => { }), ); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)]); testRecurring('testSetCachePre', () => { const set = new RRuleSet(); @@ -203,11 +169,7 @@ describe('RRuleSet', () => { }), ); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)]); testRecurring('testSetCachePost', () => { const set = new RRuleSet(); @@ -230,11 +192,7 @@ describe('RRuleSet', () => { ); set.all(); return set; - }, [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ]); + }, [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)]); testRecurring('testSetInfiniteAll', () => { const set = new RRuleSet(); @@ -258,11 +216,7 @@ describe('RRuleSet', () => { method: 'all', args: [(_: unknown, count: number) => count < 3], }; - }, [ - datetime(2007, 9, 2, 9, 0), - datetime(2008, 9, 2, 9, 0), - datetime(2009, 9, 2, 9, 0), - ]); + }, [datetime(2007, 9, 2, 9, 0), datetime(2008, 9, 2, 9, 0), datetime(2009, 9, 2, 9, 0)]); testRecurring('testSetInfiniteBetween', () => { const set = new RRuleSet(); @@ -285,11 +239,7 @@ describe('RRuleSet', () => { method: 'between', args: [datetime(2000, 9, 2, 9, 0), datetime(2010, 9, 2, 9, 0)], }; - }, [ - datetime(2007, 9, 2, 9, 0), - datetime(2008, 9, 2, 9, 0), - datetime(2009, 9, 2, 9, 0), - ]); + }, [datetime(2007, 9, 2, 9, 0), datetime(2008, 9, 2, 9, 0), datetime(2009, 9, 2, 9, 0)]); testRecurring('testSetInfiniteBefore', () => { const set = new RRuleSet(); @@ -365,10 +315,7 @@ describe('RRuleSet', () => { }), ); - expect(set.valueOf()).toEqual([ - 'DTSTART:19600101T090000Z', - 'RRULE:FREQ=YEARLY;COUNT=2', - ]); + expect(set.valueOf()).toEqual(['DTSTART:19600101T090000Z', 'RRULE:FREQ=YEARLY;COUNT=2']); }); it('generates multiline rules', () => { @@ -454,9 +401,7 @@ describe('RRuleSet', () => { set.rdate(parse('19610301T090000')); - expect(set.toString()).toEqual( - 'RDATE;TZID=America/New_York:19610201T090000,19610301T090000', - ); + expect(set.toString()).toEqual('RDATE;TZID=America/New_York:19610201T090000,19610301T090000'); }); it('generates a string with RDATE in UTC when no RRULE is present', () => { @@ -472,9 +417,7 @@ describe('RRuleSet', () => { }); it('parses RDATE strings without an RRULE', () => { - const set = rrulestr( - 'RDATE;TZID=America/New_York:19610201T090000,19610301T090000', - ) as RRuleSet; + const set = rrulestr('RDATE;TZID=America/New_York:19610201T090000,19610301T090000') as RRuleSet; expect(set).toBeInstanceOf(RRuleSet); expect(set.tzid()).toBe('America/New_York'); }); @@ -523,26 +466,10 @@ describe('RRuleSet', () => { set.rdate(datetime(2002, 3, 1, 9, 0, 0)); expect(set.all()).toEqual([ - expectedDate( - datetime(2000, 1, 1, 9, 0, 0), - currentLocalDate, - targetZone, - ), - expectedDate( - datetime(2002, 1, 1, 9, 0, 0), - currentLocalDate, - targetZone, - ), - expectedDate( - datetime(2002, 3, 1, 9, 0, 0), - currentLocalDate, - targetZone, - ), - expectedDate( - datetime(2003, 1, 1, 9, 0, 0), - currentLocalDate, - targetZone, - ), + expectedDate(datetime(2000, 1, 1, 9, 0, 0), currentLocalDate, targetZone), + expectedDate(datetime(2002, 1, 1, 9, 0, 0), currentLocalDate, targetZone), + expectedDate(datetime(2002, 3, 1, 9, 0, 0), currentLocalDate, targetZone), + expectedDate(datetime(2003, 1, 1, 9, 0, 0), currentLocalDate, targetZone), ]); resetMockDate(); @@ -553,17 +480,11 @@ describe('RRuleSet', () => { set.tzid('America/Los_Angeles'); set.rdate(datetime(2010, 11, 10, 10, 0, 0)); - expect(set.valueOf()).toEqual([ - 'RDATE;TZID=America/Los_Angeles:20101110T100000', - ]); - expect(set.toString()).toBe( - 'RDATE;TZID=America/Los_Angeles:20101110T100000', - ); + expect(set.valueOf()).toEqual(['RDATE;TZID=America/Los_Angeles:20101110T100000']); + expect(set.toString()).toBe('RDATE;TZID=America/Los_Angeles:20101110T100000'); const set2 = rrulestr(set.toString()); - expect(set2.toString()).toBe( - 'RDATE;TZID=America/Los_Angeles:20101110T100000', - ); + expect(set2.toString()).toBe('RDATE;TZID=America/Los_Angeles:20101110T100000'); }); it('generates correcty zoned recurrences when a tzid is present but no rrule is present', () => { @@ -578,11 +499,7 @@ describe('RRuleSet', () => { set.rdate(new Date(Date.parse('2002-03-01T09:00:00'))); expect(set.all()).toEqual([ - expectedDate( - new Date(Date.parse('2002-03-01T09:00:00')), - currentLocalDate, - targetZone, - ), + expectedDate(new Date(Date.parse('2002-03-01T09:00:00')), currentLocalDate, targetZone), ]); resetMockDate(); @@ -598,10 +515,7 @@ describe('RRuleSet', () => { it('updates the ruleset to exclude recurrence date', () => { const legacy = ['RRULE:DTSTART=19990104T110000Z;FREQ=DAILY;INTERVAL=1']; - const repeat = [ - 'DTSTART:19990104T110000Z', - 'RRULE:FREQ=DAILY;INTERVAL=1', - ]; + const repeat = ['DTSTART:19990104T110000Z', 'RRULE:FREQ=DAILY;INTERVAL=1']; const recurrenceDate = datetime(2017, 8, 21, 16, 0, 0); @@ -614,10 +528,7 @@ describe('RRuleSet', () => { it('updates the ruleset to exclude recurrence rule', () => { const legacy = ['RRULE:DTSTART=19990104T110000Z;FREQ=DAILY;INTERVAL=1']; - const repeat = [ - 'DTSTART:19990104T110000Z', - 'RRULE:FREQ=DAILY;INTERVAL=1', - ]; + const repeat = ['DTSTART:19990104T110000Z', 'RRULE:FREQ=DAILY;INTERVAL=1']; const exrule = new RRule({ dtstart: datetime(1999, 1, 4, 11, 0, 0), @@ -638,62 +549,33 @@ describe('RRuleSet', () => { const original = ['DTSTART:20171201T080000Z', 'RRULE:FREQ=WEEKLY']; expectRecurrence([original, legacy]).toBeUpdatedWithEndDate( - [ - 'DTSTART:20171201T080000Z', - 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959Z', - ].join('\n'), + ['DTSTART:20171201T080000Z', 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959Z'].join('\n'), ); }); it('replaces an existing end date with a new one', () => { - const legacy = [ - 'RRULE:DTSTART=20171201T080000Z;FREQ=WEEKLY;UNTIL=20180301T080000Z', - ]; - const original = [ - 'DTSTART:20171201T080000Z', - 'RRULE:FREQ=WEEKLY;UNTIL=20180301T080000Z', - ]; + const legacy = ['RRULE:DTSTART=20171201T080000Z;FREQ=WEEKLY;UNTIL=20180301T080000Z']; + const original = ['DTSTART:20171201T080000Z', 'RRULE:FREQ=WEEKLY;UNTIL=20180301T080000Z']; expectRecurrence([original, legacy]).toBeUpdatedWithEndDate( - [ - 'DTSTART:20171201T080000Z', - 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959Z', - ].join('\n'), + ['DTSTART:20171201T080000Z', 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959Z'].join('\n'), ); }); it('handles rule in a timezone', () => { - const legacy = [ - 'RRULE:DTSTART;TZID=America/New_York:20171201T080000;FREQ=WEEKLY', - ]; - const original = [ - 'DTSTART;TZID=America/New_York:20171201T080000', - 'RRULE:FREQ=WEEKLY', - ]; + const legacy = ['RRULE:DTSTART;TZID=America/New_York:20171201T080000;FREQ=WEEKLY']; + const original = ['DTSTART;TZID=America/New_York:20171201T080000', 'RRULE:FREQ=WEEKLY']; expectRecurrence([original, legacy]).toBeUpdatedWithEndDate( - [ - 'DTSTART;TZID=America/New_York:20171201T080000', - 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959', - ].join('\n'), + ['DTSTART;TZID=America/New_York:20171201T080000', 'RRULE:FREQ=WEEKLY;UNTIL=20171224T235959'].join('\n'), ); }); - const updateWithEndDate = ( - recurrence: string[], - updatedCursor: Date, - ): string => { + const updateWithEndDate = (recurrence: string[], updatedCursor: Date): string => { const oneDay = 24 * 60 * 60 * 1000; const oneDayEarlier = new Date(updatedCursor.getTime() - oneDay); const newEndDate = new Date( - Date.UTC( - oneDayEarlier.getUTCFullYear(), - oneDayEarlier.getUTCMonth(), - oneDayEarlier.getUTCDate(), - 23, - 59, - 59, - ), + Date.UTC(oneDayEarlier.getUTCFullYear(), oneDayEarlier.getUTCMonth(), oneDayEarlier.getUTCDate(), 23, 59, 59), ); const rrule = rrulestr(recurrence.join('\n')); @@ -709,10 +591,7 @@ describe('RRuleSet', () => { return newRuleSet.toString(); }; - const amendRuleSetWithExceptionDate = ( - recurrence: string[], - cursor: Date, - ): string => { + const amendRuleSetWithExceptionDate = (recurrence: string[], cursor: Date): string => { const ruleSet = rrulestr(recurrence.join('\n'), { forceset: true, }) as RRuleSet; @@ -720,10 +599,7 @@ describe('RRuleSet', () => { return ruleSet.toString(); }; - const amendRuleSetWithExceptionRule = ( - recurrence: string[], - exrule: RRule, - ): string => { + const amendRuleSetWithExceptionRule = (recurrence: string[], exrule: RRule): string => { const ruleSet = rrulestr(recurrence.join('\n'), { forceset: true, }) as RRuleSet; @@ -807,9 +683,7 @@ describe('RRuleSet', () => { }); set.exrule(rrule); - expect(set.exrules().map((e) => e.toString())).toEqual([ - rrule.toString(), - ]); + expect(set.exrules().map((e) => e.toString())).toEqual([rrule.toString()]); }); it('rdates()', () => { diff --git a/test/rrulestr.test.ts b/test/rrulestr.test.ts index d86bbdda..b985faba 100644 --- a/test/rrulestr.test.ts +++ b/test/rrulestr.test.ts @@ -1,6 +1,6 @@ import { Frequency, RRule, RRuleSet, rrulestr } from '../src'; +import { parseInput } from '../src/parse/rrulestr'; import { Days } from '../src/rrule'; -import { parseInput } from '../src/rrulestr'; import { datetime, parse, TEST_CTX, testRecurring } from './lib/utils'; describe('rrulestr', () => { @@ -23,9 +23,7 @@ describe('rrulestr', () => { }); it('parses an rrule', () => { - expect( - rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3\n'), - ).toBeInstanceOf(RRule); + expect(rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3\n')).toBeInstanceOf(RRule); }); it('parses an rrule without frequency', () => { @@ -50,53 +48,33 @@ describe('rrulestr', () => { it('parses an rruleset when there are multiple rrules', () => { expect( rrulestr( - 'DTSTART:19970902T090000Z\n' + - 'RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n' + - 'RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n', + 'DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n' + 'RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n', ), ).toBeInstanceOf(RRuleSet); }); - testRecurring( - 'testStr', - rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3\n'), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], - ); + testRecurring('testStr', rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3\n'), [ + datetime(1997, 9, 2, 9, 0), + datetime(1998, 9, 2, 9, 0), + datetime(1999, 9, 2, 9, 0), + ]); - testRecurring( - 'testStrCase', - rrulestr('dtstart:19970902T090000Z\n' + 'rrule:freq=yearly;count=3\n'), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], - ); + testRecurring('testStrCase', rrulestr('dtstart:19970902T090000Z\n' + 'rrule:freq=yearly;count=3\n'), [ + datetime(1997, 9, 2, 9, 0), + datetime(1998, 9, 2, 9, 0), + datetime(1999, 9, 2, 9, 0), + ]); - testRecurring( - 'testStrSpaces', - rrulestr(' DTSTART:19970902T090000Z ' + ' RRULE:FREQ=YEARLY;COUNT=3 '), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], - ); + testRecurring('testStrSpaces', rrulestr(' DTSTART:19970902T090000Z ' + ' RRULE:FREQ=YEARLY;COUNT=3 '), [ + datetime(1997, 9, 2, 9, 0), + datetime(1998, 9, 2, 9, 0), + datetime(1999, 9, 2, 9, 0), + ]); testRecurring( 'testStrSpacesAndLines', - rrulestr( - ' DTSTART:19970902T090000Z \n' + ' \n RRULE:FREQ=YEARLY;COUNT=3 \n', - ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], + rrulestr(' DTSTART:19970902T090000Z \n' + ' \n RRULE:FREQ=YEARLY;COUNT=3 \n'), + [datetime(1997, 9, 2, 9, 0), datetime(1998, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0)], ); testRecurring( @@ -104,11 +82,7 @@ describe('rrulestr', () => { rrulestr('RRULE:FREQ=YEARLY;COUNT=3\n', { dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1998, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0)], ); testRecurring( @@ -116,11 +90,7 @@ describe('rrulestr', () => { rrulestr('FREQ=YEARLY;COUNT=3\n', { dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1998, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0)], ); testRecurring( @@ -129,25 +99,15 @@ describe('rrulestr', () => { unfold: true, dtstart: parse('19970902T090000'), }), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1998, 9, 2, 9, 0), - datetime(1999, 9, 2, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1998, 9, 2, 9, 0), datetime(1999, 9, 2, 9, 0)], ); testRecurring( 'testStrSet', rrulestr( - 'DTSTART:19970902T090000Z\n' + - 'RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n' + - 'RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n', + 'DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=2;BYDAY=TU\n' + 'RRULE:FREQ=YEARLY;COUNT=1;BYDAY=TH\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -158,11 +118,7 @@ describe('rrulestr', () => { 'RDATE:19970904T090000Z\n' + 'RDATE:19970909T090000Z\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 4, 9, 0), - datetime(1997, 9, 9, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 4, 9, 0), datetime(1997, 9, 9, 9, 0)], ); testRecurring( @@ -172,11 +128,7 @@ describe('rrulestr', () => { 'RRULE:FREQ=YEARLY;COUNT=6;BYDAY=TU,TH\n' + 'EXRULE:FREQ=YEARLY;COUNT=3;BYDAY=TH\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -188,11 +140,7 @@ describe('rrulestr', () => { 'EXDATE:19970911T090000Z\n' + 'EXDATE:19970918T090000Z\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -209,11 +157,7 @@ describe('rrulestr', () => { 'EXDATE:19970911T090000Z\n' + 'EXDATE:19970918T090000Z\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -228,11 +172,7 @@ describe('rrulestr', () => { 'RDATE:19970918T090000Z\n' + 'EXRULE:FREQ=YEARLY;COUNT=3;BYDAY=TH\n', ), - [ - datetime(1997, 9, 2, 9, 0), - datetime(1997, 9, 9, 9, 0), - datetime(1997, 9, 16, 9, 0), - ], + [datetime(1997, 9, 2, 9, 0), datetime(1997, 9, 9, 9, 0), datetime(1997, 9, 16, 9, 0)], ); testRecurring( @@ -243,37 +183,19 @@ describe('rrulestr', () => { 'BYMONTH=3;byweekday=TH;BYMONTHDAY=3;' + 'BYHOUR=3;BYMINUTE=3;BYSECOND=3\n', ), - [ - datetime(2033, 3, 3, 3, 3, 3), - datetime(2039, 3, 3, 3, 3, 3), - datetime(2072, 3, 3, 3, 3, 3), - ], + [datetime(2033, 3, 3, 3, 3, 3), datetime(2039, 3, 3, 3, 3, 3), datetime(2072, 3, 3, 3, 3, 3)], ); testRecurring( 'testStrNWeekDay', - rrulestr( - 'DTSTART:19970902T090000Z\n' + - 'RRULE:FREQ=YEARLY;COUNT=3;BYDAY=1TU,-1TH\n', - ), - [ - datetime(1997, 12, 25, 9, 0), - datetime(1998, 1, 6, 9, 0), - datetime(1998, 12, 31, 9, 0), - ], + rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3;BYDAY=1TU,-1TH\n'), + [datetime(1997, 12, 25, 9, 0), datetime(1998, 1, 6, 9, 0), datetime(1998, 12, 31, 9, 0)], ); testRecurring( 'testStrNWeekDayLarge', - rrulestr( - 'DTSTART:19970902T090000Z\n' + - 'RRULE:FREQ=YEARLY;COUNT=3;BYDAY=13TU,-13TH\n', - ), - [ - datetime(1997, 10, 2, 9, 0), - datetime(1998, 3, 31, 9, 0), - datetime(1998, 10, 8, 9, 0), - ], + rrulestr('DTSTART:19970902T090000Z\n' + 'RRULE:FREQ=YEARLY;COUNT=3;BYDAY=13TU,-13TH\n'), + [datetime(1997, 10, 2, 9, 0), datetime(1998, 3, 31, 9, 0), datetime(1998, 10, 8, 9, 0)], ); it('parses without TZID', () => { @@ -287,8 +209,7 @@ describe('rrulestr', () => { it('parses TZID', () => { const rrule = rrulestr( - 'DTSTART;TZID=America/New_York:19970902T090000\n' + - 'RRULE:FREQ=DAILY;UNTIL=19980902T090000', + 'DTSTART;TZID=America/New_York:19970902T090000\n' + 'RRULE:FREQ=DAILY;UNTIL=19980902T090000', ); expect(rrule.origOptions).toMatchObject({ @@ -300,9 +221,7 @@ describe('rrulestr', () => { }); it('parses a DTSTART inside an RRULE', () => { - const rrule = rrulestr( - 'RRULE:UNTIL=19990404T110000Z;DTSTART=19990104T110000Z;FREQ=WEEKLY;BYDAY=TU,WE', - ); + const rrule = rrulestr('RRULE:UNTIL=19990404T110000Z;DTSTART=19990104T110000Z;FREQ=WEEKLY;BYDAY=TU,WE'); expect(rrule.options).toMatchObject({ until: datetime(1999, 4, 4, 11, 0, 0), @@ -327,9 +246,7 @@ describe('rrulestr', () => { }); it('parses a DTSTART if it is the first param', () => { - const rrule = rrulestr( - 'RRULE:DTSTART;TZID=America/Los_Angeles:20180719T111500;FREQ=DAILY;INTERVAL=1', - ); + const rrule = rrulestr('RRULE:DTSTART;TZID=America/Los_Angeles:20180719T111500;FREQ=DAILY;INTERVAL=1'); expect(rrule.options).toMatchObject({ dtstart: datetime(2018, 7, 19, 11, 15, 0), From a975338f3d69266814c4ceddfb15876ad020dd13 Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Fri, 20 Feb 2026 23:48:10 -0500 Subject: [PATCH 3/5] chore: restructure --- src/index.ts | 6 +++--- src/nlp/index.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index ab4b659c..6a7667b4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,17 @@ /* ! * rrule.js - Library for working with recurrence rules for calendar dates. - * https://github.com/shavonn/rrule + * https://github.com/offload-project/rrule * * Copyright 2010, Jakub Roztocil and Lars Schoning * Copyright 2026, Shavonn Brown * Licenced under the BSD licence. - * https://github.com/shavonn/rrule/blob/main/LICENSE + * https://github.com/offload-project/rrule/blob/main/LICENSE * * Based on: * python-dateutil - Extensions to the standard Python datetime module. * Copyright (c) 2003-2011 - Gustavo Niemeyer * Copyright (c) 2012 - Tomi Pieviläinen - * https://github.com/shavonn/rrule/blob/main/LICENSE + * https://github.com/offload-project/rrule/blob/main/LICENSE * */ diff --git a/src/nlp/index.ts b/src/nlp/index.ts index b7b3a0a2..ce23d9d8 100644 --- a/src/nlp/index.ts +++ b/src/nlp/index.ts @@ -6,12 +6,12 @@ import ToText, { type DateFormatter, type GetText } from './totext'; /* ! * rrule.js - Library for working with recurrence rules for calendar dates. - * https://github.com/shavonn/rrule + * https://github.com/offload-project/rrule * * Copyright 2010, Jakub Roztocil and Lars Schoning * Copyright 2026, Shavonn Brown * Licenced under the BSD license. - * https://github.com/shavonn/rrule/blob/main/LICENSE + * https://github.com/offload-project/rrule/blob/main/LICENSE * */ From 3522665ab9b62698f832ff0f1666d1e2683b686a Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Fri, 20 Feb 2026 23:53:37 -0500 Subject: [PATCH 4/5] chore: update badges --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 99df6b0b..ef3e6ccd 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,9 @@ **Library for working with recurrence rules for calendar dates.**

- npm version + version GitHub Actions Release Workflow Status GitHub Actions Test Workflow Status - license

rrule.js supports recurrence rules as defined in the [iCalendar RFC](https://tools.ietf.org/html/rfc5545), with a few From 98b8b24fd333b83db091f1701a5325e2ababfd04 Mon Sep 17 00:00:00 2001 From: Shavonn Brown Date: Fri, 20 Feb 2026 23:56:50 -0500 Subject: [PATCH 5/5] chore: trigger file update --- src/nlp/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/nlp/index.ts b/src/nlp/index.ts index ce23d9d8..fc30c80e 100644 --- a/src/nlp/index.ts +++ b/src/nlp/index.ts @@ -19,7 +19,6 @@ import ToText, { type DateFormatter, type GetText } from './totext'; * * Implementation of RRule.fromText() and RRule::toText(). * - * * On the client side, this file needs to be included * when those functions are used. *