node-schedule 1.2.0 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +11 -10
- package/.travis.yml +9 -2
- package/README.md +45 -17
- package/lib/schedule.js +88 -26
- package/package.json +8 -7
- package/test/.eslintrc +5 -0
- package/test/convenience-method-test.js +85 -85
- package/test/date-convenience-methods-test.js +1 -1
- package/test/job-test.js +61 -61
- package/test/recurrence-rule-test.js +81 -0
- package/test/schedule-cron-jobs.js +6 -8
- package/fff.js +0 -18
package/.eslintrc
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"env": {
|
|
3
|
-
"node": true
|
|
3
|
+
"node": true,
|
|
4
|
+
"es6": true
|
|
4
5
|
},
|
|
5
6
|
"rules": {
|
|
6
|
-
"eqeqeq": [
|
|
7
|
-
"indent": [2,
|
|
8
|
-
"no-constant-condition":
|
|
9
|
-
"no-redeclare":
|
|
10
|
-
"no-underscore-dangle":
|
|
11
|
-
"no-use-before-define": [
|
|
12
|
-
"quotes": [
|
|
13
|
-
"space-before-blocks":
|
|
14
|
-
"strict":
|
|
7
|
+
"eqeqeq": ["error", "smart"],
|
|
8
|
+
"indent": ["error", 2, { "SwitchCase": 1 }],
|
|
9
|
+
"no-constant-condition": "off",
|
|
10
|
+
"no-redeclare": "warn",
|
|
11
|
+
"no-underscore-dangle": "off",
|
|
12
|
+
"no-use-before-define": ["warn","nofunc"],
|
|
13
|
+
"quotes": ["error", "single"],
|
|
14
|
+
"space-before-blocks": "error",
|
|
15
|
+
"strict": "error"
|
|
15
16
|
}
|
|
16
17
|
}
|
package/.travis.yml
CHANGED
|
@@ -3,6 +3,13 @@ node_js:
|
|
|
3
3
|
- "0.12"
|
|
4
4
|
- "0.10"
|
|
5
5
|
- "4"
|
|
6
|
-
- "
|
|
7
|
-
|
|
6
|
+
- "6"
|
|
7
|
+
- "7"
|
|
8
|
+
before_script: >
|
|
9
|
+
if nvm ls-remote --lts | grep "$(nvm current)"; then
|
|
10
|
+
echo "running on a LTS node version, linting"
|
|
11
|
+
npm test
|
|
12
|
+
else
|
|
13
|
+
echo "running on a non-LTS node version, skipping linting"
|
|
14
|
+
fi
|
|
8
15
|
script: ./node_modules/.bin/istanbul cover ./node_modules/.bin/nodeunit test && cat ./coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf ./coverage
|
package/README.md
CHANGED
|
@@ -7,11 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
[](https://nodei.co/npm/node-schedule/)
|
|
9
9
|
|
|
10
|
-
>__Announcement:__ Node Schedule is looking for add additional collaborators
|
|
11
|
-
with commit access. If you are actively involved in open source,
|
|
12
|
-
ping [Tejas Manohar] via [email](mailto:me@tejas.io) to express interest.
|
|
13
|
-
Those who already contribute to the project are preferred.
|
|
14
|
-
|
|
15
10
|
Node Schedule is a flexible cron-like and not-cron-like job scheduler for Node.js.
|
|
16
11
|
It allows you to schedule jobs (arbitrary functions) for execution at
|
|
17
12
|
specific dates, with optional recurrence rules. It only uses a single timer
|
|
@@ -53,8 +48,9 @@ They also emit a `scheduled` event each time they're scheduled to run, and a
|
|
|
53
48
|
`canceled` event when an invocation is canceled before it's executed (both events
|
|
54
49
|
receive a JavaScript date object as a parameter). Note that jobs are scheduled the
|
|
55
50
|
first time immediately, so if you create a job using the `scheduleJob()`
|
|
56
|
-
convenience method, you'll miss the first `scheduled` event
|
|
57
|
-
`canceled` is the single-L American
|
|
51
|
+
convenience method, you'll miss the first `scheduled` event, but you can query the
|
|
52
|
+
invocation manually (see below). Also note that `canceled` is the single-L American
|
|
53
|
+
spelling.
|
|
58
54
|
|
|
59
55
|
### Cron-style Scheduling
|
|
60
56
|
|
|
@@ -81,6 +77,8 @@ var j = schedule.scheduleJob('42 * * * *', function(){
|
|
|
81
77
|
});
|
|
82
78
|
```
|
|
83
79
|
|
|
80
|
+
Execute a cron job when the minute is 42 (e.g. 19:42, 20:42, etc.).
|
|
81
|
+
|
|
84
82
|
And:
|
|
85
83
|
|
|
86
84
|
```js
|
|
@@ -113,12 +111,6 @@ var j = schedule.scheduleJob(date, function(){
|
|
|
113
111
|
});
|
|
114
112
|
```
|
|
115
113
|
|
|
116
|
-
You can invalidate the job with the `cancel()` method:
|
|
117
|
-
|
|
118
|
-
```js
|
|
119
|
-
j.cancel();
|
|
120
|
-
```
|
|
121
|
-
|
|
122
114
|
To use current data in the future you can use binding:
|
|
123
115
|
|
|
124
116
|
```js
|
|
@@ -164,10 +156,20 @@ var j = schedule.scheduleJob(rule, function(){
|
|
|
164
156
|
});
|
|
165
157
|
```
|
|
166
158
|
|
|
159
|
+
#### RecurrenceRule properties
|
|
160
|
+
|
|
161
|
+
- `second`
|
|
162
|
+
- `minute`
|
|
163
|
+
- `hour`
|
|
164
|
+
- `date`
|
|
165
|
+
- `month`
|
|
166
|
+
- `year`
|
|
167
|
+
- `dayOfWeek`
|
|
168
|
+
|
|
167
169
|
> **Note**: It's worth noting that the default value of a component of a recurrence rule is
|
|
168
|
-
`null` (except for
|
|
169
|
-
explicitly set `minute` to 0 above, the message would have instead been logged at
|
|
170
|
-
5:00pm, 5:01pm, 5:02pm, ..., 5:59pm.* Probably not what you want.
|
|
170
|
+
> `null` (except for second, which is 0 for familiarity with cron). *If we did not
|
|
171
|
+
> explicitly set `minute` to 0 above, the message would have instead been logged at
|
|
172
|
+
> 5:00pm, 5:01pm, 5:02pm, ..., 5:59pm.* Probably not what you want.
|
|
171
173
|
|
|
172
174
|
#### Object Literal Syntax
|
|
173
175
|
|
|
@@ -187,12 +189,38 @@ The ruledat supports the above.
|
|
|
187
189
|
|
|
188
190
|
```js
|
|
189
191
|
let startTime = new Date(Date.now() + 5000);
|
|
190
|
-
let endTime = new Date(
|
|
192
|
+
let endTime = new Date(startTime.getTime() + 5000);
|
|
191
193
|
var j = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * * * *' }, function(){
|
|
192
194
|
console.log('Time for tea!');
|
|
193
195
|
});
|
|
194
196
|
```
|
|
195
197
|
|
|
198
|
+
### Handle Jobs and Job Invocations
|
|
199
|
+
|
|
200
|
+
There are some function to get informations for a Job and to handle the Job and
|
|
201
|
+
Invocations.
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
#### job.cancel(reshedule)
|
|
205
|
+
You can invalidate any job with the `cancel()` method:
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
j.cancel();
|
|
209
|
+
```
|
|
210
|
+
All planned invocations will be canceled. When you set the parameter ***reschedule***
|
|
211
|
+
to true then the Job is newly scheduled afterwards.
|
|
212
|
+
|
|
213
|
+
#### job.cancelNext(reshedule)
|
|
214
|
+
This method invalidates the next planned invocation or the job.
|
|
215
|
+
When you set the parameter ***reschedule*** to true then the Job is newly scheduled
|
|
216
|
+
afterwards.
|
|
217
|
+
|
|
218
|
+
#### job.reschedule(spec)
|
|
219
|
+
This method cancels all pending invocation and registers the Job completely new again using the given specification.
|
|
220
|
+
Return true/false on success/failure.
|
|
221
|
+
|
|
222
|
+
#### job.nextInvocation()
|
|
223
|
+
This method returns a Date object for the planned next Invocation for this Job. If no invocation is planned the method returns null.
|
|
196
224
|
|
|
197
225
|
## Contributing
|
|
198
226
|
|
package/lib/schedule.js
CHANGED
|
@@ -10,10 +10,12 @@ var events = require('events'),
|
|
|
10
10
|
util = require('util'),
|
|
11
11
|
cronParser = require('cron-parser'),
|
|
12
12
|
CronDate = require('cron-parser/lib/date'),
|
|
13
|
-
lt = require('long-timeout')
|
|
13
|
+
lt = require('long-timeout'),
|
|
14
|
+
sorted = require('sorted-array-functions');
|
|
14
15
|
|
|
15
16
|
/* Job object */
|
|
16
17
|
var anonJobCounter = 0;
|
|
18
|
+
var scheduledJobs = {};
|
|
17
19
|
|
|
18
20
|
function isValidDate(date) {
|
|
19
21
|
// Taken from http://stackoverflow.com/a/12372720/1562178
|
|
@@ -60,11 +62,7 @@ function Job(name, job, callback) {
|
|
|
60
62
|
// method that require private access
|
|
61
63
|
this.trackInvocation = function(invocation) {
|
|
62
64
|
// add to our invocation list
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// and sort
|
|
66
|
-
pendingInvocations.sort(sorter);
|
|
67
|
-
|
|
65
|
+
sorted.add(pendingInvocations, invocation, sorter);
|
|
68
66
|
return true;
|
|
69
67
|
};
|
|
70
68
|
this.stopTrackingInvocation = function(invocation) {
|
|
@@ -188,33 +186,40 @@ Job.prototype.schedule = function(spec) {
|
|
|
188
186
|
var inv;
|
|
189
187
|
var start;
|
|
190
188
|
var end;
|
|
189
|
+
var tz;
|
|
191
190
|
|
|
192
191
|
if (typeof spec === 'object' && spec.rule) {
|
|
193
|
-
start = spec.start ||
|
|
194
|
-
end = spec.end ||
|
|
192
|
+
start = spec.start || undefined;
|
|
193
|
+
end = spec.end || undefined;
|
|
194
|
+
tz = spec.tz;
|
|
195
195
|
spec = spec.rule;
|
|
196
196
|
|
|
197
|
-
if (start
|
|
197
|
+
if (start) {
|
|
198
198
|
if (!(start instanceof Date)) {
|
|
199
199
|
start = new Date(start);
|
|
200
200
|
}
|
|
201
|
+
|
|
202
|
+
start = new CronDate(start, tz);
|
|
201
203
|
if (!isValidDate(start) || start.getTime() < Date.now()) {
|
|
202
|
-
start =
|
|
204
|
+
start = undefined;
|
|
203
205
|
}
|
|
204
206
|
}
|
|
205
207
|
|
|
206
|
-
if (end
|
|
207
|
-
end =
|
|
208
|
+
if (end && !(end instanceof Date) && !isValidDate(end = new Date(end))) {
|
|
209
|
+
end = undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (end) {
|
|
213
|
+
end = new CronDate(end, tz);
|
|
208
214
|
}
|
|
209
215
|
}
|
|
210
216
|
|
|
211
217
|
try {
|
|
212
|
-
var res = cronParser.parseExpression(spec, { currentDate: start });
|
|
218
|
+
var res = cronParser.parseExpression(spec, { currentDate: start, tz: tz });
|
|
213
219
|
inv = scheduleNextRecurrence(res, self, start, end);
|
|
214
220
|
if (inv !== null) {
|
|
215
221
|
success = self.trackInvocation(inv);
|
|
216
222
|
}
|
|
217
|
-
|
|
218
223
|
} catch (err) {
|
|
219
224
|
var type = typeof spec;
|
|
220
225
|
if ((type === 'string') || (type === 'number')) {
|
|
@@ -222,6 +227,7 @@ Job.prototype.schedule = function(spec) {
|
|
|
222
227
|
}
|
|
223
228
|
|
|
224
229
|
if ((spec instanceof Date) && (isValidDate(spec))) {
|
|
230
|
+
spec = new CronDate(spec);
|
|
225
231
|
if (spec.getTime() >= Date.now()) {
|
|
226
232
|
inv = new Invocation(self, spec);
|
|
227
233
|
scheduleInvocation(inv);
|
|
@@ -255,6 +261,7 @@ Job.prototype.schedule = function(spec) {
|
|
|
255
261
|
spec = r;
|
|
256
262
|
}
|
|
257
263
|
|
|
264
|
+
spec.tz = tz;
|
|
258
265
|
inv = scheduleNextRecurrence(spec, self, start, end);
|
|
259
266
|
if (inv !== null) {
|
|
260
267
|
success = self.trackInvocation(inv);
|
|
@@ -339,13 +346,68 @@ function RecurrenceRule(year, month, date, dayOfWeek, hour, minute, second) {
|
|
|
339
346
|
this.second = (second == null) ? 0 : second;
|
|
340
347
|
}
|
|
341
348
|
|
|
349
|
+
RecurrenceRule.prototype.isValid = function() {
|
|
350
|
+
function isValidType(num) {
|
|
351
|
+
if (Array.isArray(num) || (num instanceof Array)) {
|
|
352
|
+
return num.every(function(e) {
|
|
353
|
+
return isValidType(e);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
return !(Number.isNaN(Number(num)) && !(num instanceof Range));
|
|
357
|
+
}
|
|
358
|
+
if (this.month !== null && (this.month < 0 || this.month > 11 || !isValidType(this.month))) {
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
if (this.dayOfWeek !== null && (this.dayOfWeek < 0 || this.dayOfWeek > 6 || !isValidType(this.dayOfWeek))) {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
if (this.hour !== null && (this.hour < 0 || this.hour > 23 || !isValidType(this.hour))) {
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
if (this.minute !== null && (this.minute < 0 || this.minute > 59 || !isValidType(this.minute))) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
if (this.second !== null && (this.second < 0 || this.second > 59 || !isValidType(this.second))) {
|
|
371
|
+
return false;
|
|
372
|
+
}
|
|
373
|
+
if (this.date !== null) {
|
|
374
|
+
if(!isValidType(this.date)) {
|
|
375
|
+
return false;
|
|
376
|
+
}
|
|
377
|
+
switch (this.month) {
|
|
378
|
+
case 3:
|
|
379
|
+
case 5:
|
|
380
|
+
case 8:
|
|
381
|
+
case 10:
|
|
382
|
+
if (this.date < 1 || this. date > 30) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
break;
|
|
386
|
+
case 1:
|
|
387
|
+
if (this.date < 1 || this. date > 29) {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
break;
|
|
391
|
+
default:
|
|
392
|
+
if (this.date < 1 || this. date > 31) {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return true;
|
|
398
|
+
};
|
|
399
|
+
|
|
342
400
|
RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
343
|
-
base = (base instanceof Date) ? base : (new Date());
|
|
401
|
+
base = ((base instanceof CronDate) || (base instanceof Date)) ? base : (new Date());
|
|
344
402
|
if (!this.recurs) {
|
|
345
403
|
return null;
|
|
346
404
|
}
|
|
347
405
|
|
|
348
|
-
|
|
406
|
+
if(!this.isValid()) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
var now = new CronDate(Date.now(), this.tz);
|
|
349
411
|
var fullYear = now.getFullYear();
|
|
350
412
|
if ((this.year !== null) &&
|
|
351
413
|
(typeof this.year == 'number') &&
|
|
@@ -353,7 +415,7 @@ RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
|
353
415
|
return null;
|
|
354
416
|
}
|
|
355
417
|
|
|
356
|
-
var next = new CronDate(base.getTime());
|
|
418
|
+
var next = new CronDate(base.getTime(), this.tz);
|
|
357
419
|
next.addSecond();
|
|
358
420
|
|
|
359
421
|
while (true) {
|
|
@@ -402,7 +464,7 @@ RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
|
402
464
|
break;
|
|
403
465
|
}
|
|
404
466
|
|
|
405
|
-
return next;
|
|
467
|
+
return next ? next.toDate() : null;
|
|
406
468
|
};
|
|
407
469
|
|
|
408
470
|
function recurMatch(val, matcher) {
|
|
@@ -410,8 +472,10 @@ function recurMatch(val, matcher) {
|
|
|
410
472
|
return true;
|
|
411
473
|
}
|
|
412
474
|
|
|
413
|
-
if (typeof matcher === 'number'
|
|
475
|
+
if (typeof matcher === 'number') {
|
|
414
476
|
return (val === matcher);
|
|
477
|
+
} else if(typeof matcher === 'string') {
|
|
478
|
+
return (val === Number(matcher));
|
|
415
479
|
} else if (matcher instanceof Range) {
|
|
416
480
|
return matcher.contains(val);
|
|
417
481
|
} else if (Array.isArray(matcher) || (matcher instanceof Array)) {
|
|
@@ -442,10 +506,10 @@ var invocations = [];
|
|
|
442
506
|
var currentInvocation = null;
|
|
443
507
|
|
|
444
508
|
function scheduleInvocation(invocation) {
|
|
445
|
-
|
|
446
|
-
invocations.sort(sorter);
|
|
509
|
+
sorted.add(invocations, invocation, sorter);
|
|
447
510
|
prepareNextInvocation();
|
|
448
|
-
invocation.
|
|
511
|
+
var date = invocation.fireDate instanceof CronDate ? invocation.fireDate.toDate() : invocation.fireDate;
|
|
512
|
+
invocation.job.emit('scheduled', date);
|
|
449
513
|
}
|
|
450
514
|
|
|
451
515
|
function prepareNextInvocation() {
|
|
@@ -508,14 +572,14 @@ function cancelInvocation(invocation) {
|
|
|
508
572
|
/* Recurrence scheduler */
|
|
509
573
|
function scheduleNextRecurrence(rule, job, prevDate, endDate) {
|
|
510
574
|
|
|
511
|
-
prevDate = (prevDate instanceof
|
|
575
|
+
prevDate = (prevDate instanceof CronDate) ? prevDate : new CronDate();
|
|
512
576
|
|
|
513
577
|
var date = (rule instanceof RecurrenceRule) ? rule.nextInvocationDate(prevDate) : rule.next();
|
|
514
578
|
if (date === null) {
|
|
515
579
|
return null;
|
|
516
580
|
}
|
|
517
581
|
|
|
518
|
-
if ((endDate instanceof
|
|
582
|
+
if ((endDate instanceof CronDate) && date.getTime() > endDate.getTime()) {
|
|
519
583
|
return null;
|
|
520
584
|
}
|
|
521
585
|
|
|
@@ -526,8 +590,6 @@ function scheduleNextRecurrence(rule, job, prevDate, endDate) {
|
|
|
526
590
|
}
|
|
527
591
|
|
|
528
592
|
/* Convenience methods */
|
|
529
|
-
var scheduledJobs = {};
|
|
530
|
-
|
|
531
593
|
function scheduleJob() {
|
|
532
594
|
if (arguments.length < 2) {
|
|
533
595
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-schedule",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
4
4
|
"description": "A cron-like and not-cron-like job scheduler for Node.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schedule",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"main": "./lib/schedule.js",
|
|
13
13
|
"scripts": {
|
|
14
14
|
"test": "nodeunit",
|
|
15
|
-
"lint": "eslint lib"
|
|
15
|
+
"lint": "eslint lib test"
|
|
16
16
|
},
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Matt Patenaude",
|
|
@@ -24,14 +24,15 @@
|
|
|
24
24
|
"url": "https://github.com/node-schedule/node-schedule.git"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"cron-parser": "
|
|
28
|
-
"long-timeout": "0.
|
|
27
|
+
"cron-parser": "^2.4.0",
|
|
28
|
+
"long-timeout": "0.1.1",
|
|
29
|
+
"sorted-array-functions": "^1.0.0"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"coveralls": "^2.11.2",
|
|
32
|
-
"eslint": "^
|
|
33
|
-
"istanbul": "^0.
|
|
34
|
-
"nodeunit": "^0.
|
|
33
|
+
"eslint": "^3.19.0",
|
|
34
|
+
"istanbul": "^0.4.5",
|
|
35
|
+
"nodeunit": "^0.10.2",
|
|
35
36
|
"sinon": "^1.14.1"
|
|
36
37
|
}
|
|
37
38
|
}
|
|
@@ -37,32 +37,32 @@ module.exports = {
|
|
|
37
37
|
clock.tick(3250);
|
|
38
38
|
},
|
|
39
39
|
"Job doesn't emit initial 'scheduled' event": function(test) {
|
|
40
|
-
|
|
40
|
+
var job = schedule.scheduleJob(new Date(Date.now() + 1000), function() {});
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
job.on('scheduled', function() {
|
|
43
|
+
test.ok(false);
|
|
44
|
+
});
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
setTimeout(function() {
|
|
47
|
+
test.done();
|
|
48
|
+
}, 1250);
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
50
|
+
clock.tick(1250);
|
|
51
|
+
},
|
|
52
|
+
"Won't run job if scheduled in the past": function(test) {
|
|
53
|
+
test.expect(1);
|
|
54
|
+
var job = schedule.scheduleJob(new Date(Date.now() - 3000), function() {
|
|
55
|
+
test.ok(false);
|
|
56
|
+
});
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
test.equal(job, null);
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
setTimeout(function() {
|
|
61
|
+
test.done();
|
|
62
|
+
}, 1000);
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
clock.tick(1000);
|
|
65
|
+
}
|
|
66
66
|
},
|
|
67
67
|
".scheduleJob(RecurrenceRule, fn)": {
|
|
68
68
|
"Runs job at interval based on recur rule, repeating indefinitely": function(test) {
|
|
@@ -83,44 +83,44 @@ module.exports = {
|
|
|
83
83
|
clock.tick(3250);
|
|
84
84
|
},
|
|
85
85
|
"Job doesn't emit initial 'scheduled' event": function(test) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
/*
|
|
87
|
+
* If this was Job#schedule it'd fire 4 times.
|
|
88
|
+
*/
|
|
89
|
+
test.expect(3);
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
var rule = new schedule.RecurrenceRule();
|
|
92
|
+
rule.second = null; // fire every second
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
var job = new schedule.scheduleJob(rule, function() {});
|
|
95
95
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
job.on('scheduled', function(runOnDate) {
|
|
97
|
+
test.ok(true);
|
|
98
|
+
});
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
setTimeout(function() {
|
|
101
|
+
job.cancel();
|
|
102
|
+
test.done();
|
|
103
|
+
}, 3250);
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
clock.tick(3250);
|
|
106
|
+
},
|
|
107
|
+
"Doesn't invoke job if recur rule schedules it in the past": function(test) {
|
|
108
|
+
test.expect(1);
|
|
109
|
+
var rule = new schedule.RecurrenceRule();
|
|
110
|
+
rule.year = 1960;
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
var job = schedule.scheduleJob(rule, function() {
|
|
113
|
+
test.ok(false);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test.equal(job, null);
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
setTimeout(function() {
|
|
119
|
+
test.done();
|
|
120
|
+
}, 1000);
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
clock.tick(1000);
|
|
123
|
+
}
|
|
124
124
|
},
|
|
125
125
|
".scheduleJob({...}, fn)": {
|
|
126
126
|
"Runs job at interval based on object, repeating indefinitely": function(test) {
|
|
@@ -140,46 +140,46 @@ module.exports = {
|
|
|
140
140
|
clock.tick(3250);
|
|
141
141
|
},
|
|
142
142
|
"Job doesn't emit initial 'scheduled' event": function(test) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
var job = schedule.scheduleJob({
|
|
152
|
-
second: null // fire every second
|
|
153
|
-
}, function() {});
|
|
154
|
-
|
|
155
|
-
job.on('scheduled', function() {
|
|
156
|
-
test.ok(true);
|
|
157
|
-
});
|
|
143
|
+
/*
|
|
144
|
+
* With Job#schedule this would be 3:
|
|
145
|
+
* scheduled at time 0
|
|
146
|
+
* scheduled at time 1000
|
|
147
|
+
* scheduled at time 2000
|
|
148
|
+
*/
|
|
149
|
+
test.expect(2);
|
|
158
150
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}, 2250);
|
|
151
|
+
var job = schedule.scheduleJob({
|
|
152
|
+
second: null // fire every second
|
|
153
|
+
}, function() {});
|
|
163
154
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
155
|
+
job.on('scheduled', function() {
|
|
156
|
+
test.ok(true);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
setTimeout(function() {
|
|
160
|
+
job.cancel();
|
|
161
|
+
test.done();
|
|
162
|
+
}, 2250);
|
|
163
|
+
|
|
164
|
+
clock.tick(2250);
|
|
165
|
+
},
|
|
166
|
+
"Doesn't invoke job if object schedules it in the past": function(test) {
|
|
167
|
+
test.expect(1);
|
|
168
|
+
|
|
169
|
+
var job = schedule.scheduleJob({
|
|
170
|
+
year: 1960
|
|
171
|
+
}, function() {
|
|
172
|
+
test.ok(false);
|
|
173
|
+
});
|
|
168
174
|
|
|
169
|
-
|
|
170
|
-
year: 1960
|
|
171
|
-
}, function() {
|
|
172
|
-
test.ok(false);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
test.equal(job, null);
|
|
175
|
+
test.equal(job, null);
|
|
176
176
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
setTimeout(function() {
|
|
178
|
+
test.done();
|
|
179
|
+
}, 1000);
|
|
180
180
|
|
|
181
|
-
|
|
182
|
-
|
|
181
|
+
clock.tick(1000);
|
|
182
|
+
}
|
|
183
183
|
},
|
|
184
184
|
".scheduleJob({...}, {...}, fn)": {
|
|
185
185
|
"Callback called for each job if callback is provided": function(test) {
|
|
@@ -38,7 +38,7 @@ module.exports = {
|
|
|
38
38
|
}
|
|
39
39
|
},
|
|
40
40
|
"UTC": {
|
|
41
|
-
|
|
41
|
+
"Should accept a valid UTC date in milliseconds": function(test) {
|
|
42
42
|
test.expect(1);
|
|
43
43
|
|
|
44
44
|
schedule.scheduleJob(new Date(Date.now() + 1000).getTime(), function() {
|
package/test/job-test.js
CHANGED
|
@@ -154,7 +154,7 @@ module.exports = {
|
|
|
154
154
|
});
|
|
155
155
|
|
|
156
156
|
job.on('scheduled', function(runAtDate) {
|
|
157
|
-
test.equal(runAtDate, date);
|
|
157
|
+
test.equal(runAtDate.getTime(), date.getTime());
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
job.schedule(date);
|
|
@@ -199,47 +199,47 @@ module.exports = {
|
|
|
199
199
|
clock.tick(3250);
|
|
200
200
|
},
|
|
201
201
|
"Job emits 'scheduled' event for every next invocation": function(test) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
202
|
+
// Job will run 3 times but be scheduled 4 times, 4th run never happens
|
|
203
|
+
// due to cancel.
|
|
204
|
+
test.expect(4);
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
var job = new schedule.Job(function() {});
|
|
207
207
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
job.on('scheduled', function(runOnDate) {
|
|
209
|
+
test.ok(true);
|
|
210
|
+
});
|
|
211
211
|
|
|
212
|
-
|
|
213
|
-
|
|
212
|
+
var rule = new schedule.RecurrenceRule();
|
|
213
|
+
rule.second = null; // fire every second
|
|
214
214
|
|
|
215
|
-
|
|
215
|
+
job.schedule(rule);
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
217
|
+
setTimeout(function() {
|
|
218
|
+
job.cancel();
|
|
219
|
+
test.done();
|
|
220
|
+
}, 3250);
|
|
221
221
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
222
|
+
clock.tick(3250);
|
|
223
|
+
},
|
|
224
|
+
"Doesn't invoke job if recur rule schedules it in the past": function(test) {
|
|
225
|
+
test.expect(0);
|
|
226
226
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
227
|
+
var job = new schedule.Job(function() {
|
|
228
|
+
test.ok(false);
|
|
229
|
+
});
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
231
|
+
var rule = new schedule.RecurrenceRule();
|
|
232
|
+
rule.year = 2000;
|
|
233
233
|
|
|
234
|
-
|
|
234
|
+
job.schedule(rule);
|
|
235
235
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
236
|
+
setTimeout(function() {
|
|
237
|
+
job.cancel();
|
|
238
|
+
test.done();
|
|
239
|
+
}, 1000);
|
|
240
240
|
|
|
241
|
-
|
|
242
|
-
|
|
241
|
+
clock.tick(1000);
|
|
242
|
+
}
|
|
243
243
|
},
|
|
244
244
|
"#schedule({...})": {
|
|
245
245
|
"Runs job at interval based on object, repeating indefinitely": function(test) {
|
|
@@ -261,45 +261,45 @@ module.exports = {
|
|
|
261
261
|
clock.tick(3250);
|
|
262
262
|
},
|
|
263
263
|
"Job emits 'scheduled' event for every next invocation": function(test) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
264
|
+
// Job will run 3 times but be scheduled 4 times, 4th run never happens
|
|
265
|
+
// due to cancel.
|
|
266
|
+
test.expect(4);
|
|
267
267
|
|
|
268
|
-
|
|
268
|
+
var job = new schedule.Job(function() {});
|
|
269
269
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
270
|
+
job.on('scheduled', function(runOnDate) {
|
|
271
|
+
test.ok(true);
|
|
272
|
+
});
|
|
273
273
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
job.schedule({
|
|
275
|
+
second: null // Fire every second
|
|
276
|
+
});
|
|
277
277
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
278
|
+
setTimeout(function() {
|
|
279
|
+
job.cancel();
|
|
280
|
+
test.done();
|
|
281
|
+
}, 3250);
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
283
|
+
clock.tick(3250);
|
|
284
|
+
},
|
|
285
|
+
"Doesn't invoke job if object schedules it in the past": function(test) {
|
|
286
|
+
test.expect(0);
|
|
287
287
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
var job = new schedule.Job(function() {
|
|
289
|
+
test.ok(false);
|
|
290
|
+
});
|
|
291
291
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
292
|
+
job.schedule({
|
|
293
|
+
year: 2000
|
|
294
|
+
});
|
|
295
295
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
296
|
+
setTimeout(function() {
|
|
297
|
+
job.cancel();
|
|
298
|
+
test.done();
|
|
299
|
+
}, 1000);
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
clock.tick(1000);
|
|
302
|
+
}
|
|
303
303
|
},
|
|
304
304
|
"#schedule('jobName', {...})": {
|
|
305
305
|
"Runs job with a custom name input": function(test) {
|
|
@@ -288,6 +288,87 @@ module.exports = {
|
|
|
288
288
|
next = rule.nextInvocationDate(next);
|
|
289
289
|
test.equal(next, null);
|
|
290
290
|
|
|
291
|
+
test.done();
|
|
292
|
+
},
|
|
293
|
+
"using rule with string properties": function(test) {
|
|
294
|
+
var rule = new schedule.RecurrenceRule();
|
|
295
|
+
rule.second = '50';
|
|
296
|
+
rule.minute = '5';
|
|
297
|
+
rule.hour = '10';
|
|
298
|
+
var next = rule.nextInvocationDate(base);
|
|
299
|
+
test.deepEqual(new Date(2010, 3, 30, 10, 5, 50, 0), next);
|
|
300
|
+
test.done();
|
|
301
|
+
},
|
|
302
|
+
"nextInvocationDate on an invalid month should return null": function(test) {
|
|
303
|
+
var rule = new schedule.RecurrenceRule();
|
|
304
|
+
rule.month = 12;
|
|
305
|
+
var next = rule.nextInvocationDate();
|
|
306
|
+
test.equal(next, null);
|
|
307
|
+
|
|
308
|
+
var rule2 = new schedule.RecurrenceRule();
|
|
309
|
+
rule2.month = 'asdfasdf';
|
|
310
|
+
var next2 = rule2.nextInvocationDate(next);
|
|
311
|
+
test.equal(next2, null);
|
|
312
|
+
|
|
313
|
+
test.done();
|
|
314
|
+
},
|
|
315
|
+
"nextInvocationDate on an invalid second should return null": function(test) {
|
|
316
|
+
var rule = new schedule.RecurrenceRule();
|
|
317
|
+
rule.second = 60;
|
|
318
|
+
var next = rule.nextInvocationDate();
|
|
319
|
+
test.equal(next, null);
|
|
320
|
+
|
|
321
|
+
var rule2 = new schedule.RecurrenceRule();
|
|
322
|
+
rule2.second = 'asdfasdf';
|
|
323
|
+
var next2 = rule2.nextInvocationDate();
|
|
324
|
+
test.equal(next2, null);
|
|
325
|
+
|
|
326
|
+
test.done();
|
|
327
|
+
},
|
|
328
|
+
"nextInvocationDate on an invalid hour should return null": function(test) {
|
|
329
|
+
var rule = new schedule.RecurrenceRule();
|
|
330
|
+
rule.hour = 24;
|
|
331
|
+
var next = rule.nextInvocationDate();
|
|
332
|
+
test.equal(next, null);
|
|
333
|
+
|
|
334
|
+
var rule2 = new schedule.RecurrenceRule();
|
|
335
|
+
rule2.hour = 'asdfasdf';
|
|
336
|
+
var next2 = rule2.nextInvocationDate();
|
|
337
|
+
test.equal(next2, null);
|
|
338
|
+
|
|
339
|
+
test.done();
|
|
340
|
+
},
|
|
341
|
+
"nextInvocationDate on an invalid date should return null": function(test) {
|
|
342
|
+
var rule = new schedule.RecurrenceRule();
|
|
343
|
+
rule.date = 90;
|
|
344
|
+
var next = rule.nextInvocationDate();
|
|
345
|
+
test.equal(next, null);
|
|
346
|
+
|
|
347
|
+
// Test February
|
|
348
|
+
var rule2 = new schedule.RecurrenceRule();
|
|
349
|
+
rule2.month = 1;
|
|
350
|
+
rule2.date = 30;
|
|
351
|
+
var next2 = rule2.nextInvocationDate();
|
|
352
|
+
test.equal(next2, null);
|
|
353
|
+
|
|
354
|
+
var rule3 = new schedule.RecurrenceRule();
|
|
355
|
+
rule3.date = 'asdfasdf';
|
|
356
|
+
var next3 = rule3.nextInvocationDate();
|
|
357
|
+
test.equal(next3, null);
|
|
358
|
+
|
|
359
|
+
test.done();
|
|
360
|
+
},
|
|
361
|
+
"nextInvocationDate on an invalid dayOfWeek should return null": function(test) {
|
|
362
|
+
var rule = new schedule.RecurrenceRule();
|
|
363
|
+
rule.dayOfWeek = 90;
|
|
364
|
+
var next = rule.nextInvocationDate();
|
|
365
|
+
test.equal(next, null);
|
|
366
|
+
|
|
367
|
+
var rule2 = new schedule.RecurrenceRule();
|
|
368
|
+
rule2.dayOfWeek = 'asdfasdf';
|
|
369
|
+
var next2 = rule.nextInvocationDate();
|
|
370
|
+
test.equal(next2, null);
|
|
371
|
+
|
|
291
372
|
test.done();
|
|
292
373
|
}
|
|
293
374
|
}
|
|
@@ -10,9 +10,7 @@ var clock;
|
|
|
10
10
|
module.exports = {
|
|
11
11
|
".scheduleJob(cron_expr, fn)": {
|
|
12
12
|
setUp: function(cb) {
|
|
13
|
-
var now = Date.now();
|
|
14
13
|
clock = sinon.useFakeTimers();
|
|
15
|
-
clock.tick(now);
|
|
16
14
|
cb();
|
|
17
15
|
},
|
|
18
16
|
"Runs job every second": function(test) {
|
|
@@ -34,7 +32,7 @@ module.exports = {
|
|
|
34
32
|
"Runs job every minute": function(test) {
|
|
35
33
|
test.expect(3);
|
|
36
34
|
|
|
37
|
-
var timeout = 3 * 60 * 1000;
|
|
35
|
+
var timeout = 3 * 60 * 1000 + 150;
|
|
38
36
|
|
|
39
37
|
var job = schedule.scheduleJob('0 * * * * *', function() {
|
|
40
38
|
test.ok(true);
|
|
@@ -50,7 +48,7 @@ module.exports = {
|
|
|
50
48
|
"Runs job every hour": function(test) {
|
|
51
49
|
test.expect(3);
|
|
52
50
|
|
|
53
|
-
var timeout = 3 * 60 * 60 * 1000;
|
|
51
|
+
var timeout = 3 * 60 * 60 * 1000 + 150;
|
|
54
52
|
|
|
55
53
|
var job = schedule.scheduleJob('0 0 * * * *', function() {
|
|
56
54
|
test.ok(true);
|
|
@@ -66,7 +64,7 @@ module.exports = {
|
|
|
66
64
|
"Runs job every day": function(test) {
|
|
67
65
|
test.expect(3);
|
|
68
66
|
|
|
69
|
-
var timeout = 3 * 24 * 60 * 60 * 1000;
|
|
67
|
+
var timeout = 3 * 24 * 60 * 60 * 1000 + 150;
|
|
70
68
|
|
|
71
69
|
var job = schedule.scheduleJob('0 0 0 * * *', function() {
|
|
72
70
|
test.ok(true);
|
|
@@ -82,7 +80,7 @@ module.exports = {
|
|
|
82
80
|
"Runs job every week": function(test) {
|
|
83
81
|
test.expect(3);
|
|
84
82
|
|
|
85
|
-
var timeout = 3 * 7 * 24 * 60 * 60 * 1000;
|
|
83
|
+
var timeout = 3 * 7 * 24 * 60 * 60 * 1000 + 150;
|
|
86
84
|
|
|
87
85
|
var job = schedule.scheduleJob('0 0 0 * * 1', function() {
|
|
88
86
|
test.ok(true);
|
|
@@ -98,7 +96,7 @@ module.exports = {
|
|
|
98
96
|
"Runs job every month": function(test) {
|
|
99
97
|
test.expect(48);
|
|
100
98
|
|
|
101
|
-
var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000;
|
|
99
|
+
var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000 + 150;
|
|
102
100
|
|
|
103
101
|
var job = schedule.scheduleJob('0 0 0 1 * *', function() {
|
|
104
102
|
test.ok(true);
|
|
@@ -115,7 +113,7 @@ module.exports = {
|
|
|
115
113
|
"Runs job every year": function(test) {
|
|
116
114
|
test.expect(4);
|
|
117
115
|
|
|
118
|
-
var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000;
|
|
116
|
+
var timeout = 4 * 365.25 * 24 * 60 * 60 * 1000 + 150;
|
|
119
117
|
|
|
120
118
|
var job = schedule.scheduleJob('0 0 0 1 1 *', function() {
|
|
121
119
|
test.ok(true);
|
package/fff.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
var schedule = require('./');
|
|
2
|
-
|
|
3
|
-
// Create new cron for each iteration (creating 1-10 mins)
|
|
4
|
-
//for (var x = 1; x<10; x++){
|
|
5
|
-
// var rule = new schedule.RecurrenceRule();
|
|
6
|
-
// rule.minute = new schedule.Range(0, 59, x);
|
|
7
|
-
// schedule.scheduleJob(rule, function() {
|
|
8
|
-
// // Can I access the RULE which is being executed NOW somehow?!
|
|
9
|
-
// console.log(this);
|
|
10
|
-
// });
|
|
11
|
-
//}
|
|
12
|
-
|
|
13
|
-
var job = schedule.scheduleJob('* * * * * *', function() {
|
|
14
|
-
console.log(this.spec);
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
job.spec = '* * * * * *';
|
|
18
|
-
|