/** * Credit: * The vast majority of these tests were taken from * [rrulejs](https://github.com/jakubroztocil/rrule), * which itself credits the python library `dateutil.rrule` * for first creating the tests. */ import { context } from '../../../../../../tests/utilities'; import { DateTime } from '../../date-time'; import { INormalizedRuleOptions, IProvidedRuleOptions, normalizeRuleOptions, RuleOption, } from '../rule-options'; import { FrequencyPipe } from './01-frequency.pipe'; import { PipeController } from './pipe-controller'; import { RevFrequencyPipe } from './rev-01-frequency.pipe'; import { dateTime } from './test-utilities'; /** * Some helper functions are defined at bottom of this file */ function testIteration(args: { name: string; rules: IProvidedRuleOptions; result: DateTime[]; }) { describe(args.name, () => { const optionVariations: [string, IProvidedRuleOptions, DateTime[]][] = [ ['default', args.rules, args.result], [ 'duration', { ...args.rules, duration: 100 }, args.result.map(date => date.set('duration', 100)), ], ]; if (args.rules.count !== undefined) { const endVariation = { ...args.rules, end: args.result[args.result.length - 1] }; delete endVariation.count; optionVariations.push(['end instead of count', endVariation, args.result]); } optionVariations.forEach(([name, ruleVariation, resultsVariation]) => { describe(name, () => { let controller: PipeController; let rules: INormalizedRuleOptions; let options: { start?: DateTime; end?: DateTime; reverse?: boolean }; let result: DateTime[]; beforeEach(() => { // don't need date adapter because we're passing in DateTime objects rules = normalizeRuleOptions(0 as any, ruleVariation); options = {}; controller = build(rules, options); result = resultsVariation.slice(); }); it('', () => { expect(Array.from(controller._run())).toEqual(result); }); describe('options', () => { if (args.result.length > 1) { it('start', () => { options.start = result.shift()!.add(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result); }); it('end', () => { options.end = result.pop()!.subtract(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result); }); } if (args.result.length > 2) { it('start,end', () => { options.start = result.shift()!.add(1, 'millisecond'); options.end = result.pop()!.subtract(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result); }); } it('reverse', () => { options.reverse = true; controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result.reverse()); }); if (args.result.length > 1) { it('reverse,start', () => { options.reverse = true; options.start = result.shift()!.add(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result.reverse()); }); it('reverse,end', () => { options.reverse = true; options.end = result.pop()!.subtract(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result.reverse()); }); } if (args.result.length > 2) { it('reverse,start,end', () => { options.reverse = true; options.start = result.shift()!.add(1, 'millisecond'); options.end = result.pop()!.subtract(1, 'millisecond'); controller = build(rules, options); expect(Array.from(controller._run())).toEqual(result.reverse()); }); } }); }); }); }); } describe('PipeController', () => { describe('init', () => { let options: INormalizedRuleOptions; beforeEach(() => { options = { start: dateTime(2019), frequency: 'YEARLY', interval: 1, weekStart: 'MO', byDayOfMonth: [1], byDayOfWeek: ['TU'], } }) it('1', () => { const controller = build(options); expect(controller).toBeInstanceOf(PipeController); expect(controller.start).toEqual(dateTime(2019)); expect(controller.end).toEqual(undefined); expect(controller.reverse).toEqual(false); expect(controller.isInfinite).toEqual(true); expect(controller.hasDuration).toEqual(false); expect(controller.firstPipe).toBeInstanceOf(FrequencyPipe); }) it('2', () => { const controller = build(options, { start: dateTime(2018), end: dateTime(2020), reverse: true, }); expect(controller).toBeInstanceOf(PipeController); expect(controller.start).toEqual(dateTime(2019)); expect(controller.end).toEqual(dateTime(2020)); expect(controller.reverse).toEqual(true); expect(controller.isInfinite).toEqual(false); expect(controller.hasDuration).toEqual(false); expect(controller.firstPipe).toBeInstanceOf(RevFrequencyPipe); }) it('3', () => { const controller = build(options, { start: dateTime(2020), end: dateTime(2020), }); expect(controller.start).toEqual(dateTime(2020)); expect(controller.end).toEqual(dateTime(2020)); }) it('4', () => { options.count = 10; const controller = build(options, { start: dateTime(2020), end: dateTime(2021), reverse: true, }); expect(controller).toBeInstanceOf(PipeController); expect(controller.start).toEqual(dateTime(2019)); expect(controller.end).toEqual(dateTime(2021)); expect(controller.reverse).toEqual(true); expect(controller.isInfinite).toEqual(false); expect(controller.hasDuration).toEqual(false); expect(controller.firstPipe).toBeInstanceOf(FrequencyPipe); }) it('5', () => { options.count = 10; const controller = build(options); expect(controller).toBeInstanceOf(PipeController); expect(controller.start).toEqual(dateTime(2019)); expect(controller.end).toEqual(undefined); expect(controller.reverse).toEqual(false); expect(controller.isInfinite).toEqual(false); expect(controller.hasDuration).toEqual(false); expect(controller.firstPipe).toBeInstanceOf(FrequencyPipe); }) it('6', () => { options.duration = 10; options.count = 10; const controller = build(options); expect(controller).toBeInstanceOf(PipeController); expect(controller.start).toEqual(dateTime(2019)); expect(controller.end).toEqual(undefined); expect(controller.reverse).toEqual(false); expect(controller.isInfinite).toEqual(false); expect(controller.hasDuration).toEqual(true); expect(controller.firstPipe).toBeInstanceOf(FrequencyPipe); }) }); describe('_run()', () => { it('testMaxYear', () => { const controller = build({ frequency: 'YEARLY', count: 3, byMonthOfYear: [2], byDayOfMonth: [31], start: parse('99970902T090000'), interval: 1, weekStart: 'MO', }); expect(() => { Array.from(controller._run()); }).toThrowError(); }); context('YEARLY' as RuleOption.Frequency, frequency => { testIteration({ name: 'testYearly', rules: { frequency, start: dateTime(1997, 9, 2, 9), count: 3, }, result: [dateTime(1997, 9, 2, 9), dateTime(1998, 9, 2, 9), dateTime(1999, 9, 2, 9)], }); testIteration({ name: 'testYearlyInterval', rules: { frequency: 'YEARLY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1999, 9, 2, 9, 0), dateTime(2001, 9, 2, 9, 0), ], }); testIteration({ name: 'testYearlyIntervalLarge', rules: { frequency: 'YEARLY', count: 3, interval: 100, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(2097, 9, 2, 9, 0), dateTime(2197, 9, 2, 9, 0), ], }); testIteration({ name: 'testYearlyByMonth', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 2, 9, 0), dateTime(1998, 3, 2, 9, 0), dateTime(1999, 1, 2, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthDay', rules: { frequency: 'YEARLY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 9, 0), dateTime(1997, 10, 1, 9, 0), dateTime(1997, 10, 3, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthAndMonthDay', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 9, 0), dateTime(1998, 1, 7, 9, 0), dateTime(1998, 3, 5, 9, 0), ], }); testIteration({ name: 'testYearlyByWeekDay', rules: { frequency: 'YEARLY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 4, 9, 0), dateTime(1997, 9, 9, 9, 0), // dateTime(1997, 9, 12, 9, 0), // dateTime(1997, 9, 16, 9, 0), // dateTime(1997, 9, 18, 9, 0), // dateTime(1997, 9, 23, 9, 0), // dateTime(1997, 9, 25, 9, 0), ], }); testIteration({ name: 'testYearlyByNWeekDay', rules: { frequency: 'YEARLY', count: 3, byDayOfWeek: [['TU', 1], ['TH', -1]], start: parse('19970902T090000'), }, result: [ dateTime(1997, 12, 25, 9, 0), dateTime(1998, 1, 6, 9, 0), dateTime(1998, 12, 31, 9, 0), ], }); testIteration({ name: 'testYearlyByNWeekDayLarge', rules: { frequency: 'YEARLY', count: 3, byDayOfWeek: [['TU', 3], ['TH', -3]], start: parse('19970902T090000'), }, result: [ dateTime(1997, 12, 11, 9, 0), dateTime(1998, 1, 20, 9, 0), dateTime(1998, 12, 17, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthAndWeekDay', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 8, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthAndNWeekDay', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: [['TU', 1], ['TH', -1]], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 29, 9, 0), dateTime(1998, 3, 3, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthAndNWeekDayLarge', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: [['TU', 3], ['TH', -3]], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 15, 9, 0), dateTime(1998, 1, 20, 9, 0), dateTime(1998, 3, 12, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthDayAndWeekDay', rules: { frequency: 'YEARLY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 2, 3, 9, 0), dateTime(1998, 3, 3, 9, 0), ], }); testIteration({ name: 'testYearlyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'YEARLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 3, 3, 9, 0), dateTime(2001, 3, 1, 9, 0), ], }); testIteration({ name: 'testYearlyByHour', rules: { frequency: 'YEARLY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1998, 9, 2, 6, 0), dateTime(1998, 9, 2, 18, 0), ], }); testIteration({ name: 'testYearlyByMinute', rules: { frequency: 'YEARLY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1998, 9, 2, 9, 6), ], }); testIteration({ name: 'testYearlyBySecond', rules: { frequency: 'YEARLY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1998, 9, 2, 9, 0, 6), ], }); testIteration({ name: 'testYearlyByHourAndMinute', rules: { frequency: 'YEARLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1998, 9, 2, 6, 6), ], }); testIteration({ name: 'testYearlyByHourAndSecond', rules: { frequency: 'YEARLY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1998, 9, 2, 6, 0, 6), ], }); testIteration({ name: 'testYearlyByMinuteAndSecond', rules: { frequency: 'YEARLY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testYearlyByHourAndMinuteAndSecond', rules: { frequency: 'YEARLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); }); describe('MONTHLY', () => { testIteration({ name: 'testMonthly', rules: { frequency: 'MONTHLY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 10, 2, 9, 0), dateTime(1997, 11, 2, 9, 0), ], }); testIteration({ name: 'testMonthlyInterval', rules: { frequency: 'MONTHLY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 11, 2, 9, 0), dateTime(1998, 1, 2, 9, 0), ], }); testIteration({ name: 'testMonthlyIntervalLarge', rules: { frequency: 'MONTHLY', count: 3, interval: 18, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1999, 3, 2, 9, 0), dateTime(2000, 9, 2, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonth', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 2, 9, 0), dateTime(1998, 3, 2, 9, 0), dateTime(1999, 1, 2, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthDay', rules: { frequency: 'MONTHLY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 9, 0), dateTime(1997, 10, 1, 9, 0), dateTime(1997, 10, 3, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthAndMonthDay', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 9, 0), dateTime(1998, 1, 7, 9, 0), dateTime(1998, 3, 5, 9, 0), ], }); testIteration({ name: 'testMonthlyByWeekDay', rules: { frequency: 'MONTHLY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 4, 9, 0), dateTime(1997, 9, 9, 9, 0), ], }); testIteration({ name: 'testMonthlyByNWeekDay', rules: { frequency: 'MONTHLY', count: 3, byDayOfWeek: [['TU', 1], ['TH', -1]], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 25, 9, 0), dateTime(1997, 10, 7, 9, 0), ], }); testIteration({ name: 'testMonthlyByNWeekDayLarge', rules: { frequency: 'MONTHLY', count: 3, byDayOfWeek: [['TU', 3], ['TH', -3]], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 11, 9, 0), dateTime(1997, 9, 16, 9, 0), dateTime(1997, 10, 16, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthAndWeekDay', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 8, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthAndNWeekDay', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: [['TU', 1], ['TH', -1]], start: dateTime(1997, 9, 2, 9), }, result: [ dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 29, 9, 0), dateTime(1998, 3, 3, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthAndNWeekDayLarge', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: [['TU', 3], ['TH', -3]], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 15, 9, 0), dateTime(1998, 1, 20, 9, 0), dateTime(1998, 3, 12, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthDayAndWeekDay', rules: { frequency: 'MONTHLY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 2, 3, 9, 0), dateTime(1998, 3, 3, 9, 0), ], }); testIteration({ name: 'testMonthlyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'MONTHLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 3, 3, 9, 0), dateTime(2001, 3, 1, 9, 0), ], }); testIteration({ name: 'testMonthlyByHour', rules: { frequency: 'MONTHLY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1997, 10, 2, 6, 0), dateTime(1997, 10, 2, 18, 0), ], }); testIteration({ name: 'testMonthlyByMinute', rules: { frequency: 'MONTHLY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1997, 10, 2, 9, 6), ], }); testIteration({ name: 'testMonthlyBySecond', rules: { frequency: 'MONTHLY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 10, 2, 9, 0, 6), ], }); testIteration({ name: 'testMonthlyByHourAndMinute', rules: { frequency: 'MONTHLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1997, 10, 2, 6, 6), ], }); testIteration({ name: 'testMonthlyByHourAndSecond', rules: { frequency: 'MONTHLY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 10, 2, 6, 0, 6), ], }); testIteration({ name: 'testMonthlyByMinuteAndSecond', rules: { frequency: 'MONTHLY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testMonthlyByHourAndMinuteAndSecond', rules: { frequency: 'MONTHLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); testIteration({ name: 'testMonthlyNegByMonthDayJanFebForNonLeapYear', rules: { frequency: 'MONTHLY', count: 4, byDayOfMonth: [-1], start: parse('20131201T0900000'), }, result: [ dateTime(2013, 12, 31, 9, 0), dateTime(2014, 1, 31, 9, 0), dateTime(2014, 2, 28, 9, 0), dateTime(2014, 3, 31, 9, 0), ], }); testIteration({ name: 'testMonthlyNegByMonthDayJanFebForLeapYear', rules: { frequency: 'MONTHLY', count: 4, byDayOfMonth: [-1], start: parse('20151201T0900000'), }, result: [ dateTime(2015, 12, 31, 9, 0), dateTime(2016, 1, 31, 9, 0), dateTime(2016, 2, 29, 9, 0), dateTime(2016, 3, 31, 9, 0), ], }); }); describe('WEEKLY', () => { testIteration({ name: 'testWeekly', rules: { frequency: 'WEEKLY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 9, 9, 0), dateTime(1997, 9, 16, 9, 0), ], }); testIteration({ name: 'testWeeklyInterval', rules: { frequency: 'WEEKLY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 16, 9, 0), dateTime(1997, 9, 30, 9, 0), ], }); testIteration({ name: 'testWeeklyIntervalLarge', rules: { frequency: 'WEEKLY', count: 3, interval: 20, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1998, 1, 20, 9, 0), dateTime(1998, 6, 9, 9, 0), ], }); testIteration({ name: 'testWeeklyByMonth', rules: { frequency: 'WEEKLY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 13, 9, 0), dateTime(1998, 1, 20, 9, 0), ], }); testIteration({ name: 'testWeeklyByWeekDay', rules: { frequency: 'WEEKLY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 4, 9, 0), dateTime(1997, 9, 9, 9, 0), ], }); testIteration({ name: 'testWeeklyByMonthAndWeekDay', // This test is interesting, because it crosses the year // boundary in a weekly period to find day '1' as a // valid recurrence. rules: { frequency: 'WEEKLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 8, 9, 0), ], }); testIteration({ name: 'testWeeklyByHour', rules: { frequency: 'WEEKLY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1997, 9, 9, 6, 0), dateTime(1997, 9, 9, 18, 0), ], }); testIteration({ name: 'testWeeklyByMinute', rules: { frequency: 'WEEKLY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1997, 9, 9, 9, 6), ], }); testIteration({ name: 'testWeeklyBySecond', rules: { frequency: 'WEEKLY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 9, 9, 9, 0, 6), ], }); testIteration({ name: 'testWeeklyByHourAndMinute', rules: { frequency: 'WEEKLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1997, 9, 9, 6, 6), ], }); testIteration({ name: 'testWeeklyByHourAndSecond', rules: { frequency: 'WEEKLY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 9, 9, 6, 0, 6), ], }); testIteration({ name: 'testWeeklyByMinuteAndSecond', rules: { frequency: 'WEEKLY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testWeeklyByHourAndMinuteAndSecond', rules: { frequency: 'WEEKLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); testIteration({ name: 'calculates weekly recurrences correctly across DST boundaries', rules: { frequency: 'WEEKLY', start: parse('20181031T180000'), end: parse('20181115T050000'), }, result: [dateTime(2018, 10, 31, 18), dateTime(2018, 11, 7, 18), dateTime(2018, 11, 14, 18)], }); testIteration({ name: 'calculates byweekday recurrences correctly across DST boundaries', rules: { frequency: 'WEEKLY', start: parse('20181001T000000'), end: parse('20181009T000000'), byDayOfWeek: ['SU', 'WE'], }, result: [dateTime(2018, 10, 3), dateTime(2018, 10, 7)], }); testIteration({ name: 'testWkStIntervalMO', rules: { frequency: 'WEEKLY', count: 3, interval: 2, byDayOfWeek: ['TU', 'SU'], weekStart: 'MO', start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 7, 9, 0), dateTime(1997, 9, 16, 9, 0), ], }); testIteration({ name: 'testWkStIntervalSU', rules: { frequency: 'WEEKLY', count: 3, interval: 2, byDayOfWeek: ['TU', 'SU'], weekStart: 'SU', start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 14, 9, 0), dateTime(1997, 9, 16, 9, 0), ], }); }); describe('DAILY', () => { testIteration({ name: 'testDaily', rules: { frequency: 'DAILY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 3, 9, 0), dateTime(1997, 9, 4, 9, 0), ], }); testIteration({ name: 'testDailyInterval', rules: { frequency: 'DAILY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 4, 9, 0), dateTime(1997, 9, 6, 9, 0), ], }); testIteration({ name: 'testDailyIntervalLarge', rules: { frequency: 'DAILY', count: 3, interval: 92, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 12, 3, 9, 0), dateTime(1998, 3, 5, 9, 0), ], }); testIteration({ name: 'testDailyByMonth', rules: { frequency: 'DAILY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 1, 2, 9, 0), dateTime(1998, 1, 3, 9, 0), ], }); testIteration({ name: 'testDailyByMonthDay', rules: { frequency: 'DAILY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 9, 0), dateTime(1997, 10, 1, 9, 0), dateTime(1997, 10, 3, 9, 0), ], }); testIteration({ name: 'testDailyByMonthAndMonthDay', rules: { frequency: 'DAILY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 9, 0), dateTime(1998, 1, 7, 9, 0), dateTime(1998, 3, 5, 9, 0), ], }); testIteration({ name: 'testDailyByWeekDay', rules: { frequency: 'DAILY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 4, 9, 0), dateTime(1997, 9, 9, 9, 0), ], }); testIteration({ name: 'testDailyByMonthAndWeekDay', rules: { frequency: 'DAILY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 1, 6, 9, 0), dateTime(1998, 1, 8, 9, 0), ], }); testIteration({ name: 'testDailyByMonthDayAndWeekDay', rules: { frequency: 'DAILY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 2, 3, 9, 0), dateTime(1998, 3, 3, 9, 0), ], }); testIteration({ name: 'testDailyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'DAILY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 9, 0), dateTime(1998, 3, 3, 9, 0), dateTime(2001, 3, 1, 9, 0), ], }); testIteration({ name: 'testDailyByHour', rules: { frequency: 'DAILY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1997, 9, 3, 6, 0), dateTime(1997, 9, 3, 18, 0), ], }); testIteration({ name: 'testDailyByMinute', rules: { frequency: 'DAILY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1997, 9, 3, 9, 6), ], }); testIteration({ name: 'testDailyBySecond', rules: { frequency: 'DAILY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 9, 3, 9, 0, 6), ], }); testIteration({ name: 'testDailyByHourAndMinute', rules: { frequency: 'DAILY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1997, 9, 3, 6, 6), ], }); testIteration({ name: 'testDailyByHourAndSecond', rules: { frequency: 'DAILY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 9, 3, 6, 0, 6), ], }); testIteration({ name: 'testDailyByMinuteAndSecond', rules: { frequency: 'DAILY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testDailyByHourAndMinuteAndSecond', rules: { frequency: 'DAILY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); testIteration({ name: 'calculates daily recurrences correctly across DST boundaries', rules: { frequency: 'DAILY', start: parse('20181101T110000'), end: parse('20181106T110000'), }, result: [ dateTime(2018, 11, 1, 11), dateTime(2018, 11, 2, 11), dateTime(2018, 11, 3, 11), dateTime(2018, 11, 4, 11), dateTime(2018, 11, 5, 11), dateTime(2018, 11, 6, 11), ], }); }); describe('HOURLY', () => { testIteration({ name: 'testHourly', rules: { frequency: 'HOURLY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 10, 0), dateTime(1997, 9, 2, 11, 0), ], }); testIteration({ name: 'testHourlyInterval', rules: { frequency: 'HOURLY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 11, 0), dateTime(1997, 9, 2, 13, 0), ], }); testIteration({ name: 'testHourlyIntervalLarge', rules: { frequency: 'HOURLY', count: 3, interval: 769, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 10, 4, 10, 0), dateTime(1997, 11, 5, 11, 0), ], }); testIteration({ name: 'testHourlyByMonth', rules: { frequency: 'HOURLY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 1, 0), dateTime(1998, 1, 1, 2, 0), ], }); testIteration({ name: 'testHourlyByMonthDay', rules: { frequency: 'HOURLY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 0, 0), dateTime(1997, 9, 3, 1, 0), dateTime(1997, 9, 3, 2, 0), ], }); testIteration({ name: 'testHourlyByMonthAndMonthDay', rules: { frequency: 'HOURLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 0, 0), dateTime(1998, 1, 5, 1, 0), dateTime(1998, 1, 5, 2, 0), ], }); testIteration({ name: 'testHourlyByWeekDay', rules: { frequency: 'HOURLY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 10, 0), dateTime(1997, 9, 2, 11, 0), ], }); testIteration({ name: 'testHourlyByMonthAndWeekDay', rules: { frequency: 'HOURLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 1, 0), dateTime(1998, 1, 1, 2, 0), ], }); testIteration({ name: 'testHourlyByMonthDayAndWeekDay', rules: { frequency: 'HOURLY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 1, 0), dateTime(1998, 1, 1, 2, 0), ], }); testIteration({ name: 'testHourlyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'HOURLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 1, 0), dateTime(1998, 1, 1, 2, 0), ], }); testIteration({ name: 'testHourlyByHour', rules: { frequency: 'HOURLY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1997, 9, 3, 6, 0), dateTime(1997, 9, 3, 18, 0), ], }); testIteration({ name: 'testHourlyByMinute', rules: { frequency: 'HOURLY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1997, 9, 2, 10, 6), ], }); testIteration({ name: 'testHourlyBySecond', rules: { frequency: 'HOURLY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 9, 2, 10, 0, 6), ], }); testIteration({ name: 'testHourlyByHourAndMinute', rules: { frequency: 'HOURLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1997, 9, 3, 6, 6), ], }); testIteration({ name: 'testHourlyByHourAndSecond', rules: { frequency: 'HOURLY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 9, 3, 6, 0, 6), ], }); testIteration({ name: 'testHourlyByMinuteAndSecond', rules: { frequency: 'HOURLY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testHourlyByHourAndMinuteAndSecond', rules: { frequency: 'HOURLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); }); describe('MINUTELY', () => { testIteration({ name: 'testMinutely', rules: { frequency: 'MINUTELY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 9, 1), dateTime(1997, 9, 2, 9, 2), ], }); testIteration({ name: 'testMinutelyInterval', rules: { frequency: 'MINUTELY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 9, 2), dateTime(1997, 9, 2, 9, 4), ], }); testIteration({ name: 'testMinutelyIntervalLarge', rules: { frequency: 'MINUTELY', count: 3, interval: 1501, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 3, 10, 1), dateTime(1997, 9, 4, 11, 2), ], }); testIteration({ name: 'testMinutelyByMonth', rules: { frequency: 'MINUTELY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 0, 1), dateTime(1998, 1, 1, 0, 2), ], }); testIteration({ name: 'testMinutelyByMonthDay', rules: { frequency: 'MINUTELY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 0, 0), dateTime(1997, 9, 3, 0, 1), dateTime(1997, 9, 3, 0, 2), ], }); testIteration({ name: 'testMinutelyByMonthAndMonthDay', rules: { frequency: 'MINUTELY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 0, 0), dateTime(1998, 1, 5, 0, 1), dateTime(1998, 1, 5, 0, 2), ], }); testIteration({ name: 'testMinutelyByWeekDay', rules: { frequency: 'MINUTELY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0), dateTime(1997, 9, 2, 9, 1), dateTime(1997, 9, 2, 9, 2), ], }); testIteration({ name: 'testMinutelyByMonthAndWeekDay', rules: { frequency: 'MINUTELY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 0, 1), dateTime(1998, 1, 1, 0, 2), ], }); testIteration({ name: 'testMinutelyByMonthDayAndWeekDay', rules: { frequency: 'MINUTELY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 0, 1), dateTime(1998, 1, 1, 0, 2), ], }); testIteration({ name: 'testMinutelyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'MINUTELY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0), dateTime(1998, 1, 1, 0, 1), dateTime(1998, 1, 1, 0, 2), ], }); testIteration({ name: 'testMinutelyByHour', rules: { frequency: 'MINUTELY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0), dateTime(1997, 9, 2, 18, 1), dateTime(1997, 9, 2, 18, 2), ], }); testIteration({ name: 'testMinutelyByMinute', rules: { frequency: 'MINUTELY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6), dateTime(1997, 9, 2, 9, 18), dateTime(1997, 9, 2, 10, 6), ], }); testIteration({ name: 'testMinutelyBySecond', rules: { frequency: 'MINUTELY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 9, 2, 9, 1, 6), ], }); testIteration({ name: 'testMinutelyByHourAndMinute', rules: { frequency: 'MINUTELY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6), dateTime(1997, 9, 2, 18, 18), dateTime(1997, 9, 3, 6, 6), ], }); testIteration({ name: 'testMinutelyByHourAndSecond', rules: { frequency: 'MINUTELY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 9, 2, 18, 1, 6), ], }); testIteration({ name: 'testMinutelyByMinuteAndSecond', rules: { frequency: 'MINUTELY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testMinutelyByHourAndMinuteAndSecond', rules: { frequency: 'MINUTELY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T180606'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); }); describe('SECONDLY', () => { testIteration({ name: 'testSecondly', rules: { frequency: 'SECONDLY', count: 3, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 0), dateTime(1997, 9, 2, 9, 0, 1), dateTime(1997, 9, 2, 9, 0, 2), ], }); testIteration({ name: 'testSecondlyInterval', rules: { frequency: 'SECONDLY', count: 3, interval: 2, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 0), dateTime(1997, 9, 2, 9, 0, 2), dateTime(1997, 9, 2, 9, 0, 4), ], }); testIteration({ name: 'testSecondlyIntervalLarge', rules: { frequency: 'SECONDLY', count: 3, interval: 90061, start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 0), dateTime(1997, 9, 3, 10, 1, 1), dateTime(1997, 9, 4, 11, 2, 2), ], }); testIteration({ name: 'testSecondlyByMonth', rules: { frequency: 'SECONDLY', count: 3, byMonthOfYear: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0, 0), dateTime(1998, 1, 1, 0, 0, 1), dateTime(1998, 1, 1, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByMonthDay', rules: { frequency: 'SECONDLY', count: 3, byDayOfMonth: [1, 3], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 3, 0, 0, 0), dateTime(1997, 9, 3, 0, 0, 1), dateTime(1997, 9, 3, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByMonthAndMonthDay', rules: { frequency: 'SECONDLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [5, 7], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 5, 0, 0, 0), dateTime(1998, 1, 5, 0, 0, 1), dateTime(1998, 1, 5, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByWeekDay', rules: { frequency: 'SECONDLY', count: 3, byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 0), dateTime(1997, 9, 2, 9, 0, 1), dateTime(1997, 9, 2, 9, 0, 2), ], }); testIteration({ name: 'testSecondlyByMonthAndWeekDay', rules: { frequency: 'SECONDLY', count: 3, byMonthOfYear: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0, 0), dateTime(1998, 1, 1, 0, 0, 1), dateTime(1998, 1, 1, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByMonthDayAndWeekDay', rules: { frequency: 'SECONDLY', count: 3, byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0, 0), dateTime(1998, 1, 1, 0, 0, 1), dateTime(1998, 1, 1, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByMonthAndMonthDayAndWeekDay', rules: { frequency: 'SECONDLY', count: 3, byMonthOfYear: [1, 3], byDayOfMonth: [1, 3], byDayOfWeek: ['TU', 'TH'], start: parse('19970902T090000'), }, result: [ dateTime(1998, 1, 1, 0, 0, 0), dateTime(1998, 1, 1, 0, 0, 1), dateTime(1998, 1, 1, 0, 0, 2), ], }); testIteration({ name: 'testSecondlyByHour', rules: { frequency: 'SECONDLY', count: 3, byHourOfDay: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 0), dateTime(1997, 9, 2, 18, 0, 1), dateTime(1997, 9, 2, 18, 0, 2), ], }); testIteration({ name: 'testSecondlyByMinute', rules: { frequency: 'SECONDLY', count: 3, byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 0), dateTime(1997, 9, 2, 9, 6, 1), dateTime(1997, 9, 2, 9, 6, 2), ], }); testIteration({ name: 'testSecondlyBySecond', rules: { frequency: 'SECONDLY', count: 3, bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 0, 6), dateTime(1997, 9, 2, 9, 0, 18), dateTime(1997, 9, 2, 9, 1, 6), ], }); testIteration({ name: 'testSecondlyByHourAndMinute', rules: { frequency: 'SECONDLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 0), dateTime(1997, 9, 2, 18, 6, 1), dateTime(1997, 9, 2, 18, 6, 2), ], }); testIteration({ name: 'testSecondlyByHourAndSecond', rules: { frequency: 'SECONDLY', count: 3, byHourOfDay: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 0, 6), dateTime(1997, 9, 2, 18, 0, 18), dateTime(1997, 9, 2, 18, 1, 6), ], }); testIteration({ name: 'testSecondlyByMinuteAndSecond', rules: { frequency: 'SECONDLY', count: 3, byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 9, 6, 6), dateTime(1997, 9, 2, 9, 6, 18), dateTime(1997, 9, 2, 9, 18, 6), ], }); testIteration({ name: 'testSecondlyByHourAndMinuteAndSecond', rules: { frequency: 'SECONDLY', count: 3, byHourOfDay: [6, 18], byMinuteOfHour: [6, 18], bySecondOfMinute: [6, 18], start: parse('19970902T090000'), }, result: [ dateTime(1997, 9, 2, 18, 6, 6), dateTime(1997, 9, 2, 18, 6, 18), dateTime(1997, 9, 2, 18, 18, 6), ], }); }); describe('MILLISECONDLY', () => { testIteration({ name: 'testMillisecondly', rules: { frequency: 'MILLISECONDLY', count: 3, start: dateTime(2000, 9, 2, 9, 0, 1, 0), }, result: [ dateTime(2000, 9, 2, 9, 0, 1, 0), dateTime(2000, 9, 2, 9, 0, 1, 1), dateTime(2000, 9, 2, 9, 0, 1, 2), ], }); testIteration({ name: 'testMillisecondlyInterval', rules: { frequency: 'MILLISECONDLY', count: 3, interval: 2, start: dateTime(2000, 9, 2, 9, 0, 1, 0), }, result: [ dateTime(2000, 9, 2, 9, 0, 1, 0), dateTime(2000, 9, 2, 9, 0, 1, 2), dateTime(2000, 9, 2, 9, 0, 1, 4), ], }); }); }); }); function build( options: INormalizedRuleOptions, args: { start?: DateTime; end?: DateTime; reverse?: boolean } = {}, ) { return new PipeController(options, args); } function parse(str: string) { const parts: number[] = str .match(/^(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})/)! .map(part => Number(part)); parts.shift(); return dateTime(...parts); }