node-schedule 1.2.2 → 1.3.0
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 +7 -1
- package/README.md +37 -9
- package/lib/schedule.js +69 -15
- package/package.json +3 -3
- package/test/.eslintrc +5 -0
- package/test/cancel-long-running-jobs.js +24 -0
- package/test/convenience-method-test.js +85 -85
- package/test/date-convenience-methods-test.js +1 -1
- package/test/job-test.js +83 -60
- package/test/recurrence-rule-test.js +72 -2
- package/test/start-end-test.js +16 -1
- package/.npmignore +0 -2
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
|
@@ -5,5 +5,11 @@ node_js:
|
|
|
5
5
|
- "4"
|
|
6
6
|
- "6"
|
|
7
7
|
- "7"
|
|
8
|
-
before_script:
|
|
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
|
|
9
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
|
@@ -48,8 +48,9 @@ They also emit a `scheduled` event each time they're scheduled to run, and a
|
|
|
48
48
|
`canceled` event when an invocation is canceled before it's executed (both events
|
|
49
49
|
receive a JavaScript date object as a parameter). Note that jobs are scheduled the
|
|
50
50
|
first time immediately, so if you create a job using the `scheduleJob()`
|
|
51
|
-
convenience method, you'll miss the first `scheduled` event
|
|
52
|
-
`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.
|
|
53
54
|
|
|
54
55
|
### Cron-style Scheduling
|
|
55
56
|
|
|
@@ -57,7 +58,7 @@ The cron format consists of:
|
|
|
57
58
|
```
|
|
58
59
|
* * * * * *
|
|
59
60
|
┬ ┬ ┬ ┬ ┬ ┬
|
|
60
|
-
│ │ │ │ │
|
|
61
|
+
│ │ │ │ │ │
|
|
61
62
|
│ │ │ │ │ └ day of week (0 - 7) (0 or 7 is Sun)
|
|
62
63
|
│ │ │ │ └───── month (1 - 12)
|
|
63
64
|
│ │ │ └────────── day of month (1 - 31)
|
|
@@ -88,6 +89,13 @@ var j = schedule.scheduleJob('0 17 ? * 0,4-6', function(){
|
|
|
88
89
|
|
|
89
90
|
Execute a cron job every 5 Minutes = */5 * * * *
|
|
90
91
|
|
|
92
|
+
You can also get when it is scheduled to run for every invocation of the job:
|
|
93
|
+
```js
|
|
94
|
+
var j = schedule.scheduleJob('0 1 * * *', function(fireDate){
|
|
95
|
+
console.log('This job was supposed to run at ' + fireDate + ', but actually ran at ' + new Date());
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
This is useful when you need to check if there is a delay of the job invocation when the system is busy, or save a record of all invocations of a job for audit purpose.
|
|
91
99
|
#### Unsupported Cron Features
|
|
92
100
|
|
|
93
101
|
Currently, `W` (nearest weekday), `L` (last day of month/week), and `#` (nth weekday
|
|
@@ -110,12 +118,6 @@ var j = schedule.scheduleJob(date, function(){
|
|
|
110
118
|
});
|
|
111
119
|
```
|
|
112
120
|
|
|
113
|
-
You can invalidate the job with the `cancel()` method:
|
|
114
|
-
|
|
115
|
-
```js
|
|
116
|
-
j.cancel();
|
|
117
|
-
```
|
|
118
|
-
|
|
119
121
|
To use current data in the future you can use binding:
|
|
120
122
|
|
|
121
123
|
```js
|
|
@@ -200,6 +202,32 @@ var j = schedule.scheduleJob({ start: startTime, end: endTime, rule: '*/1 * * *
|
|
|
200
202
|
});
|
|
201
203
|
```
|
|
202
204
|
|
|
205
|
+
### Handle Jobs and Job Invocations
|
|
206
|
+
|
|
207
|
+
There are some function to get informations for a Job and to handle the Job and
|
|
208
|
+
Invocations.
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
#### job.cancel(reshedule)
|
|
212
|
+
You can invalidate any job with the `cancel()` method:
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
j.cancel();
|
|
216
|
+
```
|
|
217
|
+
All planned invocations will be canceled. When you set the parameter ***reschedule***
|
|
218
|
+
to true then the Job is newly scheduled afterwards.
|
|
219
|
+
|
|
220
|
+
#### job.cancelNext(reshedule)
|
|
221
|
+
This method invalidates the next planned invocation or the job.
|
|
222
|
+
When you set the parameter ***reschedule*** to true then the Job is newly scheduled
|
|
223
|
+
afterwards.
|
|
224
|
+
|
|
225
|
+
#### job.reschedule(spec)
|
|
226
|
+
This method cancels all pending invocation and registers the Job completely new again using the given specification.
|
|
227
|
+
Return true/false on success/failure.
|
|
228
|
+
|
|
229
|
+
#### job.nextInvocation()
|
|
230
|
+
This method returns a Date object for the planned next Invocation for this Job. If no invocation is planned the method returns null.
|
|
203
231
|
|
|
204
232
|
## Contributing
|
|
205
233
|
|
package/lib/schedule.js
CHANGED
|
@@ -15,6 +15,7 @@ var events = require('events'),
|
|
|
15
15
|
|
|
16
16
|
/* Job object */
|
|
17
17
|
var anonJobCounter = 0;
|
|
18
|
+
var scheduledJobs = {};
|
|
18
19
|
|
|
19
20
|
function isValidDate(date) {
|
|
20
21
|
// Taken from http://stackoverflow.com/a/12372720/1562178
|
|
@@ -166,12 +167,12 @@ function Job(name, job, callback) {
|
|
|
166
167
|
|
|
167
168
|
util.inherits(Job, events.EventEmitter);
|
|
168
169
|
|
|
169
|
-
Job.prototype.invoke = function() {
|
|
170
|
+
Job.prototype.invoke = function(fireDate) {
|
|
170
171
|
if (typeof this.job == 'function') {
|
|
171
172
|
this.setTriggeredJobs(this.triggeredJobs() + 1);
|
|
172
|
-
this.job();
|
|
173
|
+
this.job(fireDate);
|
|
173
174
|
} else {
|
|
174
|
-
this.job.execute();
|
|
175
|
+
this.job.execute(fireDate);
|
|
175
176
|
}
|
|
176
177
|
};
|
|
177
178
|
|
|
@@ -190,8 +191,8 @@ Job.prototype.schedule = function(spec) {
|
|
|
190
191
|
if (typeof spec === 'object' && spec.rule) {
|
|
191
192
|
start = spec.start || undefined;
|
|
192
193
|
end = spec.end || undefined;
|
|
193
|
-
spec = spec.rule;
|
|
194
194
|
tz = spec.tz;
|
|
195
|
+
spec = spec.rule;
|
|
195
196
|
|
|
196
197
|
if (start) {
|
|
197
198
|
if (!(start instanceof Date)) {
|
|
@@ -345,12 +346,67 @@ function RecurrenceRule(year, month, date, dayOfWeek, hour, minute, second) {
|
|
|
345
346
|
this.second = (second == null) ? 0 : second;
|
|
346
347
|
}
|
|
347
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
|
+
|
|
348
400
|
RecurrenceRule.prototype.nextInvocationDate = function(base) {
|
|
349
401
|
base = ((base instanceof CronDate) || (base instanceof Date)) ? base : (new Date());
|
|
350
402
|
if (!this.recurs) {
|
|
351
403
|
return null;
|
|
352
404
|
}
|
|
353
405
|
|
|
406
|
+
if(!this.isValid()) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
|
|
354
410
|
var now = new CronDate(Date.now(), this.tz);
|
|
355
411
|
var fullYear = now.getFullYear();
|
|
356
412
|
if ((this.year !== null) &&
|
|
@@ -435,15 +491,15 @@ function recurMatch(val, matcher) {
|
|
|
435
491
|
|
|
436
492
|
/* Date-based scheduler */
|
|
437
493
|
function runOnDate(date, job) {
|
|
438
|
-
var now =
|
|
494
|
+
var now = Date.now();
|
|
439
495
|
var then = date.getTime();
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
496
|
+
|
|
497
|
+
return lt.setTimeout(function() {
|
|
498
|
+
if (then > Date.now())
|
|
499
|
+
runOnDate(date, job);
|
|
500
|
+
else
|
|
501
|
+
job();
|
|
502
|
+
}, (then < now ? 0 : then - now));
|
|
447
503
|
}
|
|
448
504
|
|
|
449
505
|
var invocations = [];
|
|
@@ -484,7 +540,7 @@ function prepareNextInvocation() {
|
|
|
484
540
|
|
|
485
541
|
job.stopTrackingInvocation(cinv);
|
|
486
542
|
|
|
487
|
-
job.invoke();
|
|
543
|
+
job.invoke(cinv.fireDate instanceof CronDate ? cinv.fireDate.toDate() : cinv.fireDate);
|
|
488
544
|
job.emit('run');
|
|
489
545
|
});
|
|
490
546
|
}
|
|
@@ -534,8 +590,6 @@ function scheduleNextRecurrence(rule, job, prevDate, endDate) {
|
|
|
534
590
|
}
|
|
535
591
|
|
|
536
592
|
/* Convenience methods */
|
|
537
|
-
var scheduledJobs = {};
|
|
538
|
-
|
|
539
593
|
function scheduleJob() {
|
|
540
594
|
if (arguments.length < 2) {
|
|
541
595
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-schedule",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
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",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"coveralls": "^2.11.2",
|
|
33
|
-
"eslint": "^
|
|
33
|
+
"eslint": "^3.19.0",
|
|
34
34
|
"istanbul": "^0.4.5",
|
|
35
35
|
"nodeunit": "^0.10.2",
|
|
36
36
|
"sinon": "^1.14.1"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var schedule = require('../lib/schedule');
|
|
4
|
+
|
|
5
|
+
module.exports = {
|
|
6
|
+
'Cancel Long Running Job': {
|
|
7
|
+
'should work even when recurring jobs are to be run on the past': function (test) {
|
|
8
|
+
var ok = true;
|
|
9
|
+
var job = schedule.scheduleJob('*/1 * * * * *', function () {
|
|
10
|
+
test.ok(ok);
|
|
11
|
+
var time = Date.now();
|
|
12
|
+
while (ok && (Date.now() - time < 2000)) {
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test.ok(job);
|
|
17
|
+
setTimeout(function () {
|
|
18
|
+
job.cancel();
|
|
19
|
+
test.done();
|
|
20
|
+
ok = false;
|
|
21
|
+
}, 2100);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
@@ -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
|
@@ -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) {
|
|
@@ -484,6 +484,29 @@ module.exports = {
|
|
|
484
484
|
test.done();
|
|
485
485
|
}, 2250);
|
|
486
486
|
|
|
487
|
+
clock.tick(2250);
|
|
488
|
+
},
|
|
489
|
+
"Job gets invoked with the fire date": function (test) {
|
|
490
|
+
test.expect(2);
|
|
491
|
+
var prevFireDate;
|
|
492
|
+
var job = new schedule.Job(function (fireDate) {
|
|
493
|
+
if (!prevFireDate) {
|
|
494
|
+
test.ok(fireDate instanceof Date);
|
|
495
|
+
} else {
|
|
496
|
+
test.equal(fireDate.getTime() - prevFireDate.getTime(), 1000);
|
|
497
|
+
}
|
|
498
|
+
prevFireDate = fireDate;
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
job.schedule({
|
|
502
|
+
second: null // fire every second
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
setTimeout(function () {
|
|
506
|
+
job.cancel();
|
|
507
|
+
test.done();
|
|
508
|
+
}, 2250);
|
|
509
|
+
|
|
487
510
|
clock.tick(2250);
|
|
488
511
|
}
|
|
489
512
|
},
|
|
@@ -295,10 +295,80 @@ module.exports = {
|
|
|
295
295
|
rule.second = '50';
|
|
296
296
|
rule.minute = '5';
|
|
297
297
|
rule.hour = '10';
|
|
298
|
-
|
|
299
298
|
var next = rule.nextInvocationDate(base);
|
|
300
|
-
|
|
301
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
|
+
|
|
302
372
|
test.done();
|
|
303
373
|
}
|
|
304
374
|
}
|
package/test/start-end-test.js
CHANGED
|
@@ -28,6 +28,7 @@ module.exports = {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
setTimeout(function () {
|
|
31
|
+
job.cancel();
|
|
31
32
|
test.done();
|
|
32
33
|
}, 3250);
|
|
33
34
|
|
|
@@ -49,6 +50,7 @@ module.exports = {
|
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
setTimeout(function () {
|
|
53
|
+
job.cancel();
|
|
52
54
|
test.done();
|
|
53
55
|
}, 3250);
|
|
54
56
|
|
|
@@ -70,6 +72,7 @@ module.exports = {
|
|
|
70
72
|
});
|
|
71
73
|
|
|
72
74
|
setTimeout(function () {
|
|
75
|
+
job.cancel();
|
|
73
76
|
test.done();
|
|
74
77
|
}, 3250);
|
|
75
78
|
|
|
@@ -91,6 +94,7 @@ module.exports = {
|
|
|
91
94
|
});
|
|
92
95
|
|
|
93
96
|
setTimeout(function () {
|
|
97
|
+
job.cancel();
|
|
94
98
|
test.done();
|
|
95
99
|
}, 3250);
|
|
96
100
|
|
|
@@ -113,6 +117,7 @@ module.exports = {
|
|
|
113
117
|
});
|
|
114
118
|
|
|
115
119
|
setTimeout(function () {
|
|
120
|
+
job.cancel();
|
|
116
121
|
test.done();
|
|
117
122
|
}, 3250);
|
|
118
123
|
|
|
@@ -133,6 +138,7 @@ module.exports = {
|
|
|
133
138
|
});
|
|
134
139
|
|
|
135
140
|
setTimeout(function () {
|
|
141
|
+
job.cancel();
|
|
136
142
|
test.done();
|
|
137
143
|
}, 3250);
|
|
138
144
|
|
|
@@ -151,6 +157,7 @@ module.exports = {
|
|
|
151
157
|
});
|
|
152
158
|
|
|
153
159
|
setTimeout(function () {
|
|
160
|
+
job.cancel();
|
|
154
161
|
test.done();
|
|
155
162
|
}, 3250);
|
|
156
163
|
|
|
@@ -169,6 +176,7 @@ module.exports = {
|
|
|
169
176
|
});
|
|
170
177
|
|
|
171
178
|
setTimeout(function () {
|
|
179
|
+
job.cancel();
|
|
172
180
|
test.done();
|
|
173
181
|
}, 3250);
|
|
174
182
|
|
|
@@ -187,6 +195,7 @@ module.exports = {
|
|
|
187
195
|
});
|
|
188
196
|
|
|
189
197
|
setTimeout(function () {
|
|
198
|
+
job.cancel();
|
|
190
199
|
test.done();
|
|
191
200
|
}, 3250);
|
|
192
201
|
|
|
@@ -206,6 +215,7 @@ module.exports = {
|
|
|
206
215
|
});
|
|
207
216
|
|
|
208
217
|
setTimeout(function () {
|
|
218
|
+
job.cancel();
|
|
209
219
|
test.done();
|
|
210
220
|
}, 3250);
|
|
211
221
|
|
|
@@ -226,6 +236,7 @@ module.exports = {
|
|
|
226
236
|
});
|
|
227
237
|
|
|
228
238
|
setTimeout(function () {
|
|
239
|
+
job.cancel();
|
|
229
240
|
test.done();
|
|
230
241
|
}, 3250);
|
|
231
242
|
|
|
@@ -244,6 +255,7 @@ module.exports = {
|
|
|
244
255
|
});
|
|
245
256
|
|
|
246
257
|
setTimeout(function () {
|
|
258
|
+
job.cancel();
|
|
247
259
|
test.done();
|
|
248
260
|
}, 3250);
|
|
249
261
|
|
|
@@ -262,6 +274,7 @@ module.exports = {
|
|
|
262
274
|
});
|
|
263
275
|
|
|
264
276
|
setTimeout(function () {
|
|
277
|
+
job.cancel();
|
|
265
278
|
test.done();
|
|
266
279
|
}, 3250);
|
|
267
280
|
|
|
@@ -280,6 +293,7 @@ module.exports = {
|
|
|
280
293
|
});
|
|
281
294
|
|
|
282
295
|
setTimeout(function () {
|
|
296
|
+
job.cancel();
|
|
283
297
|
test.done();
|
|
284
298
|
}, 3250);
|
|
285
299
|
|
|
@@ -299,6 +313,7 @@ module.exports = {
|
|
|
299
313
|
});
|
|
300
314
|
|
|
301
315
|
setTimeout(function () {
|
|
316
|
+
job.cancel();
|
|
302
317
|
test.done();
|
|
303
318
|
}, 3250);
|
|
304
319
|
|
|
@@ -309,4 +324,4 @@ module.exports = {
|
|
|
309
324
|
clock.restore();
|
|
310
325
|
cb();
|
|
311
326
|
}
|
|
312
|
-
};
|
|
327
|
+
};
|
package/.npmignore
DELETED