12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409 |
- var test = require('tap').test;
- var CronExpression = require('../lib/expression');
- var CronDate = require('../lib/date');
- test('empty expression test', function(t) {
- try {
- var interval = CronExpression.parse('');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addMinute();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes(), date.getMinutes(), 'Schedule matches');
- t.end();
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- });
- test('default expression test', function(t) {
- try {
- var interval = CronExpression.parse('* * * * *');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addMinute();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes(), date.getMinutes(), 'Schedule matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('default expression (tab separate) test', function(t) {
- try {
- var interval = CronExpression.parse('* * * * *');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addMinute();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes(), date.getMinutes(), 'Schedule matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('default expression (multi-space separated) test 1', function(t) {
- try {
- var interval = CronExpression.parse('* \t*\t\t *\t * \t\t*');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addMinute();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes(), date.getMinutes(), 'Schedule matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('default expression (multi-space separated) test 1', function(t) {
- try {
- var interval = CronExpression.parse('* \t *\t \t * * \t \t *');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addMinute();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes(), date.getMinutes(), 'Schedule matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('61 * * * * *');
- }, new Error('Constraint error, got value 61 expected range 0-59'));
- t.end();
- });
- test('second value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('-1 * * * * *');
- }, new Error('Constraint error, got value -1 expected range 0-59'));
- t.end();
- });
- test('invalid range', function(t) {
- t.throws(function() {
- CronExpression.parse('- * * * * *');
- }, new Error('Invalid range: -'));
- t.end();
- });
- test('minute value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('* 32,72 * * * *');
- }, new Error('Constraint error, got value 72 expected range 0-59'));
- t.end();
- });
- test('hour value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('* * 12-36 * * *');
- }, new Error('Constraint error, got range 12-36 expected range 0-23'));
- t.end();
- });
- test('day of the month value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('* * * 10-15,40 * *');
- }, ('Constraint error, got value 40 expected range 1-31'));
- t.end();
- });
- test('month value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('* * * * */10,12-13 *');
- }, new Error('Constraint error, got range 12-13 expected range 1-12'));
- t.end();
- });
- test('day of the week value out of the range', function(t) {
- t.throws(function() {
- CronExpression.parse('* * * * * 9');
- }, new Error('Constraint error, got value 9 expected range 0-7'));
- t.end();
- });
- test('invalid expression that contains too many fields', function (t) {
- t.throws(function() {
- CronExpression.parse('* * * * * * * *ASD');
- }, new Error('Invalid cron expression'));
- t.end();
- });
- test('invalid explicit day of month definition', function(t) {
- t.throws(function() {
- const iter = CronExpression.parse('0 0 31 4 *');
- iter.next();
- }, new Error('Invalid explicit day of month definition'));
- t.end();
- });
- test('incremental minutes expression test', function(t) {
- try {
- var interval = CronExpression.parse('*/3 * * * *');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getMinutes() % 3, 0, 'Schedule matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('fixed expression test', function(t) {
- try {
- var interval = CronExpression.parse('10 2 12 8 0');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of Month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- t.equal(next.getHours(), 2, 'Hour matches');
- t.equal(next.getMinutes(), 10, 'Minute matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('invalid characters test - symbol', function(t) {
- t.throws(function() {
- CronExpression.parse('10 ! 12 8 0');
- }, new Error('Invalid characters, got value: !'));
- t.end();
- });
- test('invalid characters test - letter', function(t) {
- t.throws(function() {
- CronExpression.parse('10 x 12 8 0');
- }, new Error('Invalid characters, got value: x'));
- t.end();
- });
- test('invalid characters test - parentheses', function(t) {
- t.throws(function() {
- CronExpression.parse('10 ) 12 8 0');
- }, new Error('Invalid characters, got value: )'));
- t.end();
- });
- test('interval with invalid characters test', function(t) {
- t.throws(function() {
- CronExpression.parse('10 */A 12 8 0');
- }, new Error('Invalid characters, got value: */A'));
- t.end();
- });
- test('range with invalid characters test', function(t) {
- t.throws(function() {
- CronExpression.parse('10 0-z 12 8 0');
- }, new Error('Invalid characters, got value: 0-z'));
- t.end();
- });
- test('group with invalid characters test', function(t) {
- t.throws(function() {
- CronExpression.parse('10 0,1,z 12 8 0');
- }, new Error('Invalid characters, got value: 0,1,z'));
- t.end();
- });
- test('invalid expression which has repeat 0 times', function(t) {
- t.throws(function() {
- CronExpression.parse('0 */0 * * *');
- }, new Error('Constraint error, cannot repeat at every 0 time.'));
- t.end();
- });
- test('invalid expression which has repeat negative number times', function(t) {
- t.throws(function() {
- CronExpression.parse('0 */-5 * * *');
- }, new Error('Constraint error, cannot repeat at every -5 time.'));
- t.end();
- });
- test('range test with value and repeat (second)', function(t) {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('0/30 * * * * ?', options);
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.equal(next.getSeconds(), 0);
- next = interval.next();
- t.equal(next.getSeconds(), 30);
- next = interval.next();
- t.equal(next.getSeconds(), 0);
- t.end();
- });
- test('range test with value and repeat (minute)', function(t) {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('6/23 * * * *', options);
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.equal(next.getMinutes(), 52);
- next = interval.next();
- t.equal(next.getMinutes(), 6);
- next = interval.next();
- t.equal(next.getMinutes(), 29);
- next = interval.next();
- t.equal(next.getMinutes(), 52);
- t.end();
- });
- test('range test with iterator', function(t) {
- try {
- var interval = CronExpression.parse('10-30 2 12 8 0');
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(20);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- t.equal(next.getHours(), 2, 'Hour matches');
- t.equal(next.getMinutes(), 10 + i, 'Minute matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('incremental range test with iterator', function(t) {
- try {
- var interval = CronExpression.parse('10-30/2 2 12 8 0');
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(10);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- t.equal(next.getHours(), 2, 'Hour matches');
- t.equal(next.getMinutes(), 10 + (i * 2), 'Minute matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('predefined expression', function(t) {
- try {
- var interval = CronExpression.parse('@yearly');
- t.ok(interval, 'Interval parsed');
- var date = new CronDate();
- date.addYear();
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getFullYear(), date.getFullYear(), 'Year matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression limited with start and end date', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53'),
- startDate: new CronDate('Wed, 26 Dec 2012 12:40:00'),
- endDate: new CronDate('Wed, 26 Dec 2012 16:40:00')
- };
- var interval = CronExpression.parse('*/20 * * * *', options);
- t.ok(interval, 'Interval parsed');
- var dates = interval.iterate(10);
- t.equal(dates.length, 7, 'Dates count matches for positive iteration');
- interval.reset();
- var dates = interval.iterate(-10);
- t.equal(dates.length, 6, 'Dates count matches for negative iteration');
- interval.reset();
- // Forward iteration
- var next = interval.next();
- t.equal(next.getHours(), 14, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 15, 'Hour matches');
- t.equal(next.getMinutes(), 0, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 15, 'Hour matches');
- t.equal(next.getMinutes(), 20, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 15, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 16, 'Hour matches');
- t.equal(next.getMinutes(), 0, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 16, 'Hour matches');
- t.equal(next.getMinutes(), 20, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 16, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- try {
- interval.next();
- t.ok(false, 'Should fail');
- } catch (e) {
- t.ok(true, 'Failed as expected');
- }
- next = interval.prev();
- t.equal(next.getHours(), 16, 'Hour matches');
- t.equal(next.getMinutes(), 20, 'Minute matches');
- interval.reset();
- // Backward iteration
- var prev = interval.prev();
- t.equal(prev.getHours(), 14, 'Hour matches');
- t.equal(prev.getMinutes(), 20, 'Minute matches');
- prev = interval.prev();
- t.equal(prev.getHours(), 14, 'Hour matches');
- t.equal(prev.getMinutes(), 0, 'Minute matches');
- prev = interval.prev();
- t.equal(prev.getHours(), 13, 'Hour matches');
- t.equal(prev.getMinutes(), 40, 'Minute matches');
- prev = interval.prev();
- t.equal(prev.getHours(), 13, 'Hour matches');
- t.equal(prev.getMinutes(), 20, 'Minute matches');
- prev = interval.prev();
- t.equal(prev.getHours(), 13, 'Hour matches');
- t.equal(prev.getMinutes(), 0, 'Minute matches');
- prev = interval.prev();
- t.equal(prev.getHours(), 12, 'Hour matches');
- t.equal(prev.getMinutes(), 40, 'Minute matches');
- try {
- interval.prev();
- t.ok(false, 'Should fail');
- } catch (e) {
- t.ok(true, 'Failed as expected');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('reset to given date', function(t){
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('*/20 * * * *', options);
- t.ok(interval, 'Interval parsed');
- // Forward iteration
- var next = interval.next();
- t.equal(next.getHours(), 14, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- interval.reset(); // defaults to initial currentDate
- next = interval.next();
- t.equal(next.getHours(), 14, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- interval.reset(new CronDate('Wed, 26 Dec 2012 17:23:53'));
- next = interval.next();
- t.equal(next.getHours(), 17, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- next = interval.next();
- t.equal(next.getHours(), 18, 'Hour matches');
- t.equal(next.getMinutes(), 0, 'Minute matches');
- interval.reset(new Date('2019-06-18T08:18:36.000'));
- next = interval.prev();
- t.equal(next.getDate(), 18, 'Date matches');
- t.equal(next.getHours(), 8, 'Hour matches');
- t.equal(next.getMinutes(), 0, 'Minute matches');
- next = interval.prev();
- t.equal(next.getDate(), 18, 'Date matches');
- t.equal(next.getHours(), 7, 'Hour matches');
- t.equal(next.getMinutes(), 40, 'Minute matches');
- t.end();
- } catch (err) {
- t.ifError(err, 'Reset error');
- }
- });
- test('parse expression as UTC', function(t) {
- try {
- var options = {
- utc: true
- };
- var interval = CronExpression.parse('0 0 10 * * *', options);
- var date = interval.next();
- t.equal(date.getUTCHours(), 10, 'Correct UTC hour value');
- t.equal(date.getHours(), 10, 'Correct UTC hour value');
- interval = CronExpression.parse('0 */5 * * * *', options);
- var date = interval.next(), now = new Date();
- now.setMinutes(now.getMinutes() + 5 - (now.getMinutes() % 5));
- t.equal(date.getHours(), now.getUTCHours(), 'Correct local time for 5 minute interval');
- } catch (err) {
- t.ifError(err, 'UTC parse error');
- }
- t.end();
- });
- test('expression using days of week strings', function(t) {
- try {
- var interval = CronExpression.parse('15 10 * * MON-TUE');
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(8);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- var day = next.getDay();
- t.ok(next, 'Found next scheduled interval');
- t.ok(day == 1 || day == 2, 'Day matches')
- t.equal(next.getHours(), 10, 'Hour matches');
- t.equal(next.getMinutes(), 15, 'Minute matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression using mixed days of week strings', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('15 10 * jAn-FeB mOn-tUE', options);
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(8);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- var day = next.getDay();
- var month = next.getMonth();
- t.ok(next, 'Found next scheduled interval');
- t.ok(month == 0 || month == 2, 'Month Matches');
- t.ok(day == 1 || day == 2, 'Day matches');
- t.equal(next.getHours(), 10, 'Hour matches');
- t.equal(next.getMinutes(), 15, 'Minute matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression using non-standard second field (wildcard)', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:00'),
- endDate: new CronDate('Wed, 26 Dec 2012 15:40:00')
- };
- var interval = CronExpression.parse('* * * * * *', options);
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(10);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getSeconds(), i + 1, 'Second matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression using non-standard second field (step)', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:00'),
- endDate: new CronDate('Wed, 26 Dec 2012 15:40:00')
- };
- var interval = CronExpression.parse('*/20 * * * * *', options);
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(3);
- t.ok(intervals, 'Found intervals');
- t.equal(intervals[0].getSeconds(), 20, 'Second matches');
- t.equal(intervals[1].getSeconds(), 40, 'Second matches');
- t.equal(intervals[2].getSeconds(), 0, 'Second matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression using non-standard second field (range)', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:00'),
- endDate: new CronDate('Wed, 26 Dec 2012 15:40:00')
- };
- var interval = CronExpression.parse('20-40/10 * * * * *', options);
- t.ok(interval, 'Interval parsed');
- var intervals = interval.iterate(3);
- t.ok(intervals, 'Found intervals');
- for (var i = 0, c = intervals.length; i < c; i++) {
- var next = intervals[i];
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getSeconds(), 20 + (i * 10), 'Second matches');
- }
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('expression using explicit month definition and */5 day of month step', function(t) {
- var firstIterator = CronExpression.parse('0 12 */5 6 *', {
- currentDate: '2019-06-01T11:00:00.000'
- });
- var firstExpectedDates = [
- new CronDate('2019-06-01T12:00:00.000'),
- new CronDate('2019-06-06T12:00:00.000'),
- new CronDate('2019-06-11T12:00:00.000'),
- new CronDate('2019-06-16T12:00:00.000'),
- new CronDate('2019-06-21T12:00:00.000'),
- new CronDate('2019-06-26T12:00:00.000'),
- new CronDate('2020-06-01T12:00:00.000')
- ];
- firstExpectedDates.forEach(function(expectedDate) {
- t.equal(expectedDate.toISOString(), firstIterator.next().toISOString());
- });
- var secondIterator = CronExpression.parse('0 15 */5 5 *', {
- currentDate: '2019-05-01T11:00:00.000'
- });
- var secondExpectedDates = [
- new CronDate('2019-05-01T15:00:00.000'),
- new CronDate('2019-05-06T15:00:00.000'),
- new CronDate('2019-05-11T15:00:00.000'),
- new CronDate('2019-05-16T15:00:00.000'),
- new CronDate('2019-05-21T15:00:00.000'),
- new CronDate('2019-05-26T15:00:00.000'),
- new CronDate('2019-05-31T15:00:00.000'),
- new CronDate('2020-05-01T15:00:00.000')
- ];
- secondExpectedDates.forEach(function(expectedDate) {
- t.equal(expectedDate.toISOString(), secondIterator.next().toISOString());
- });
- t.end();
- });
- test('day of month and week are both set', function(t) {
- try {
- var interval = CronExpression.parse('10 2 12 8 0');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of month is unspecified', function(t) {
- try {
- var interval = CronExpression.parse('10 2 ? * 3');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok(next.getDay() === 3, 'day of week matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok(next.getDay() === 3, 'day of week matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok(next.getDay() === 3, 'day of week matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok(next.getDay() === 3, 'day of week matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of week is unspecified', function(t) {
- try {
- var interval = CronExpression.parse('10 2 3,6 * ?');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok(next.getDate() === 3 || next.getDate() === 6, 'date matches');
- var prevDate = next.getDate();
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok((next.getDate() === 3 || next.getDate() === 6) &&
- next.getDate() !== prevDate, 'date matches and is not previous date');
- prevDate = next.getDate();
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok((next.getDate() === 3 || next.getDate() === 6) &&
- next.getDate() !== prevDate, 'date matches and is not previous date');
- prevDate = next.getDate();
- next = interval.next();
- t.ok(next, 'Found next scheduled interal');
- t.ok((next.getDate() === 3 || next.getDate() === 6) &&
- next.getDate() !== prevDate, 'date matches and is not previous date');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('Summertime bug test', function(t) {
- try {
- var month = new CronDate().getMonth() + 1;
- var interval = CronExpression.parse('0 0 0 1 '+month+' *');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- // Before fix the bug it was getting a timeout error if you are
- // in a timezone that changes the DST to ST in the hour 00:00h.
- t.ok(next, 'Found next scheduled interval');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of month and week are both set and dow is 7', function(t) {
- try {
- var interval = CronExpression.parse('10 2 12 8 7');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of month and week are both set and dow is 6,0', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('10 2 12 8 6,0', options);
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 0 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of month and week are both set and dow is 6-7', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('10 2 12 8 6-7', options);
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- // next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.ok(next.getDay() === 6 || next.getDate() === 12, 'Day or day of month matches');
- t.equal(next.getMonth(), 7, 'Month matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day of month validation should be ignored when day of month is wildcard and month is set', function (t) {
- try {
- var interval = CronExpression.parse('* * * * 2 *');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getHours(), 0, 'Hours matches');
- t.equal(next.getDate(), 1, 'Day of month matches');
- t.equal(next.getMonth() + 1, 2, 'Month matches');
- t.ok(next, 'Found next scheduled interval');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('day and date in week should matches', function(t){
- try {
- var interval = CronExpression.parse('0 1 1 1 * 1');
- t.ok(interval, 'Interval parsed');
- var next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getHours(), 1, 'Hours matches');
- t.ok(next.getDay() === 1 || next.getDate() === 1, 'Day or day of month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getHours(), 1, 'Hours matches');
- t.ok(next.getDay() === 1 || next.getDate() === 1, 'Day or day of month matches');
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getHours(), 1, 'Hours matches');
- t.ok(next.getDay() === 1 || next.getDate() === 1, 'Day or day of month matches');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should sort ranges and values in ascending order', function(t) {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53')
- };
- var interval = CronExpression.parse('0 12,13,10,1-3 * * *', options);
- t.ok(interval, 'Interval parsed');
- var hours = [ 1, 2, 3, 10, 12, 13 ];
- for (var i in hours) {
- next = interval.next();
- t.ok(next, 'Found next scheduled interval');
- t.equal(next.getHours(), hours[i], 'Hours matches');
- }
- t.end();
- });
- test('valid ES6 iterator should be returned if iterator options is set to true', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53'),
- endDate: new CronDate('Wed, 26 Dec 2012 15:40:00'),
- iterator: true
- };
- var val = null;
- var interval = CronExpression.parse('*/25 * * * *', options);
- t.ok(interval, 'Interval parsed');
- val = interval.next();
- t.ok(val, 'Next iteration resolved');
- t.ok(val.value, 'Iterator value is set');
- t.notOk(val.done, 'Iterator is not finished');
- val = interval.next();
- t.ok(val, 'Next iteration resolved');
- t.ok(val.value, 'Iterator value is set');
- t.notOk(val.done, 'Iterator is not finished');
- val = interval.next();
- t.ok(val, 'Next iteration resolved');
- t.ok(val.value, 'Iterator value is set');
- t.ok(val.done, 'Iterator is finished');
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('dow 6,7 6,0 0,6 7,6 should be equivalent', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 14:38:53'),
- };
- var expressions = [
- '30 16 * * 6,7',
- '30 16 * * 6,0',
- '30 16 * * 0,6',
- '30 16 * * 7,6'
- ];
- expressions.forEach(function(expression) {
- var interval = CronExpression.parse(expression, options);
- t.ok(interval, 'Interval parsed');
- var val = interval.next();
- t.equal(val.getDay(), 6, 'Day matches');
- val = interval.next();
- t.equal(val.getDay(), 0, 'Day matches');
- val = interval.next();
- t.equal(val.getDay(), 6, 'Day matches');
- });
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('hour 0 9,11,1 * * * and 0 1,9,11 * * * should be equivalent', function(t) {
- try {
- var options = {
- currentDate: new CronDate('Wed, 26 Dec 2012 00:00:00'),
- };
- var expressions = [
- '0 9,11,1 * * *',
- '0 1,9,11 * * *'
- ];
- expressions.forEach(function(expression) {
- var interval = CronExpression.parse(expression, options);
- t.ok(interval, 'Interval parsed');
- var val = interval.next();
- t.equal(val.getHours(), 1, 'Hour matches');
- val = interval.next();
- t.equal(val.getHours(), 9, 'Hour matches');
- val = interval.next();
- t.equal(val.getHours(), 11, 'Hour matches');
- val = interval.next();
- t.equal(val.getHours(), 1, 'Hour matches');
- val = interval.next();
- t.equal(val.getHours(), 9, 'Hour matches');
- val = interval.next();
- t.equal(val.getHours(), 11, 'Hour matches');
- });
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('it will work with #139 issue case', function(t) {
- var options = {
- currentDate : new Date('2018-11-15T16:15:33.522Z'),
- tz: 'Europe/Madrid'
- };
- var interval = CronExpression.parse('0 0 0 1,2 * *', options);
- var date = interval.next();
- t.equal(date.getFullYear(), 2018);
- t.equal(date.getDate(), 1);
- t.equal(date.getMonth(), 11);
- t.end();
- });
- test('should work for valid first/second/third/fourth/fifth occurence dayOfWeek (# char)', function(t) {
- try {
- var options = {
- currentDate: new CronDate('2019-04-30')
- };
- var expectedFirstDates = [
- new CronDate('2019-05-05'),
- new CronDate('2019-06-02'),
- new CronDate('2019-07-07'),
- new CronDate('2019-08-04')
- ];
- var expectedSecondDates = [
- new CronDate('2019-05-12'),
- new CronDate('2019-06-9'),
- new CronDate('2019-07-14'),
- new CronDate('2019-08-11')
- ];
- var expectedThirdDates = [
- new CronDate('2019-05-19'),
- new CronDate('2019-06-16'),
- new CronDate('2019-07-21'),
- new CronDate('2019-08-18')
- ];
- var expectedFourthDates = [
- new CronDate('2019-05-26'),
- new CronDate('2019-06-23'),
- new CronDate('2019-07-28'),
- new CronDate('2019-08-25')
- ];
- var expectedFifthDates = [
- new CronDate('2019-6-30'),
- new CronDate('2019-9-29'),
- new CronDate('2019-12-29'),
- new CronDate('2020-03-29')
- ];
- var allExpectedDates = [
- expectedFirstDates,
- expectedSecondDates,
- expectedThirdDates,
- expectedFourthDates,
- expectedFifthDates
- ];
- var expressions = [
- '0 0 0 ? * 0#1',
- '0 0 0 ? * 0#2',
- '0 0 0 ? * 0#3',
- '0 0 0 ? * 0#4',
- '0 0 0 ? * 0#5'
- ];
- expressions.forEach(function(expression, index) {
- var interval = CronExpression.parse(expression, options);
- var expectedDates = allExpectedDates[index];
- expectedDates.forEach(function(expected) {
- var date = interval.next();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "' + expression + '" has next() that matches expected: ' + expected.toISOString()
- );
- });
- expectedDates
- .slice(0, expectedDates.length - 1)
- .reverse()
- .forEach(function(expected) {
- var date = interval.prev();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "' + expression + '" has prev() that matches expected: ' + expected.toISOString()
- );
- });
- });
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should work for valid second sunday in may', function(t) {
- try {
- var options = {
- currentDate: new CronDate('2019-01-30')
- };
- var expectedDates = [
- new CronDate('2019-05-12'),
- new CronDate('2020-05-10'),
- new CronDate('2021-05-09'),
- new CronDate('2022-05-08')
- ];
- var interval = CronExpression.parse('0 0 0 ? MAY 0#2', options);
- expectedDates.forEach(function(expected) {
- var date = interval.next();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 0 ? MAY 0#2" has next() that matches expected: ' + expected.toISOString()
- );
- });
- expectedDates
- .slice(0, expectedDates.length - 1)
- .reverse()
- .forEach(function(expected) {
- var date = interval.prev();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 0 ? MAY 0#2" has prev() that matches expected: ' + expected.toISOString()
- );
- });
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should work for valid second sunday at noon in may', function(t) {
- try {
- var options = {
- currentDate: new CronDate('2019-05-12T11:59:00.000')
- };
- var expected = new CronDate('2019-05-12T12:00:00.000');
- var interval = CronExpression.parse('0 0 12 ? MAY 0#2', options);
- var date = interval.next();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 12 ? MAY 0#2" has next() that matches expected: ' + expected.toISOString()
- );
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should work for valid second sunday at noon in may (UTC+3)', function(t) {
- try {
- var options = {
- currentDate: new CronDate('2019-05-12T11:59:00.000', 'Europe/Sofia')
- };
- var expected = new CronDate('2019-05-12T12:00:00.000', 'Europe/Sofia');
- var interval = CronExpression.parse('0 0 12 ? MAY 0#2', options);
- var date = interval.next();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 12 ? MAY 0#2" has next() that matches expected: ' + expected.toISOString()
- );
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should work with both dayOfMonth and nth occurence of dayOfWeek', function(t) {
- try {
- var options = {
- currentDate: new CronDate('2019-04-01')
- };
- var expectedDates = [
- new CronDate('2019-04-16'),
- new CronDate('2019-04-17'),
- new CronDate('2019-04-18'),
- new CronDate('2019-05-15'),
- new CronDate('2019-05-16'),
- new CronDate('2019-05-18'),
- ];
- var interval = CronExpression.parse('0 0 0 16,18 * 3#3', options);
- expectedDates.forEach(function(expected) {
- var date = interval.next();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 0 16,18 * 3#3" has next() that matches expected: ' + expected.toISOString()
- );
- });
- expectedDates
- .slice(0, expectedDates.length - 1)
- .reverse()
- .forEach(function(expected) {
- var date = interval.prev();
- t.equal(
- date.toISOString(),
- expected.toISOString(),
- 'Expression "0 0 0 16,18 * 3#3" has prev() that matches expected: ' + expected.toISOString()
- );
- });
- } catch (err) {
- t.ifError(err, 'Interval parse error');
- }
- t.end();
- });
- test('should error when passed invalid occurence value', function(t) {
- var expressions = [
- '0 0 0 ? * 1#',
- '0 0 0 ? * 1#0',
- '0 0 0 ? * 4#6',
- '0 0 0 ? * 0##4',
- ];
- expressions.forEach(function(expression) {
- t.throws(function() {
- CronExpression.parse(expression);
- }, new Error('Constraint error, invalid dayOfWeek occurrence number (#)'), expression);
- });
- t.end();
- });
- // The Quartz documentation says that if the # character is used then no other expression can be used in the dayOfWeek term: http://www.quartz-scheduler.org/api/2.3.0/index.html
- test('cannot combine `-` range and # occurrence special characters', function(t) {
- var expression = '0 0 0 ? * 2-4#2';
- t.throws(function() {
- CronExpression.parse(expression);
- }, new Error('Constraint error, invalid dayOfWeek `#` and `-` special characters are incompatible'));
- t.end();
- });
- test('cannot combine `/` repeat interval and # occurrence special characters', function(t) {
- var expression = '0 0 0 ? * 1/2#3';
- t.throws(function() {
- CronExpression.parse(expression);
- }, new Error('Constraint error, invalid dayOfWeek `#` and `/` special characters are incompatible'));
- t.end();
- });
- test('cannot combine `,` list and # occurrence special characters', function(t) {
- var expression = '0 0 0 ? * 0,6#4';
- t.throws(function() {
- CronExpression.parse(expression);
- }, new Error('Constraint error, invalid dayOfWeek `#` and `,` special characters are incompatible'));
- t.end();
- });
|