Node-Red configuration
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

crontime.test.js 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /* eslint-disable no-new */
  2. const sinon = require('sinon');
  3. const cron = require('../lib/cron');
  4. const moment = require('moment-timezone');
  5. describe('crontime', function() {
  6. it('should test stars (* * * * * *)', function() {
  7. expect(function() {
  8. new cron.CronTime('* * * * * *');
  9. }).not.toThrow();
  10. });
  11. it('should test digit (0 * * * * *)', function() {
  12. expect(function() {
  13. new cron.CronTime('0 * * * * *');
  14. }).not.toThrow();
  15. });
  16. it('should test multi digits (08 * * * * *)', function() {
  17. expect(function() {
  18. new cron.CronTime('08 * * * * *');
  19. }).not.toThrow();
  20. });
  21. it('should test all digits (08 8 8 8 8 5)', function() {
  22. expect(function() {
  23. new cron.CronTime('08 * * * * *');
  24. }).not.toThrow();
  25. });
  26. it('should test too many digits (08 8 8 8 8 5)', function() {
  27. expect(function() {
  28. new cron.CronTime('08 * * * * *');
  29. }).not.toThrow();
  30. });
  31. it('should test standard cron format (* * * * *)', function() {
  32. expect(function() {
  33. new cron.CronTime('* * * * *');
  34. }).not.toThrow();
  35. });
  36. it('should test standard cron format (8 8 8 8 5)', function() {
  37. const standard = new cron.CronTime('8 8 8 8 5');
  38. const extended = new cron.CronTime('0 8 8 8 8 5');
  39. expect(standard.dayOfWeek).toEqual(extended.dayOfWeek);
  40. expect(standard.month).toEqual(extended.month);
  41. expect(standard.dayOfMonth).toEqual(extended.dayOfMonth);
  42. expect(standard.hour).toEqual(extended.hour);
  43. expect(standard.minute).toEqual(extended.minute);
  44. expect(standard.second).toEqual(extended.second);
  45. });
  46. it('should test hyphen (0-10 * * * * *)', function() {
  47. expect(function() {
  48. new cron.CronTime('0-10 * * * * *');
  49. }).not.toThrow();
  50. });
  51. it('should test multi hyphens (0-10 0-10 * * * *)', function() {
  52. expect(function() {
  53. new cron.CronTime('0-10 0-10 * * * *');
  54. }).not.toThrow();
  55. });
  56. it('should test all hyphens (0-10 0-10 1-10 1-10 0-6 0-1)', function() {
  57. expect(function() {
  58. new cron.CronTime('0-10 0-10 1-10 1-10 0-6 0-1');
  59. }).not.toThrow();
  60. });
  61. it('should test comma (0,10 * * * * *)', function() {
  62. expect(function() {
  63. new cron.CronTime('0,10 * * * * *');
  64. }).not.toThrow();
  65. });
  66. it('should test multi commas (0,10 0,10 * * * *)', function() {
  67. expect(function() {
  68. new cron.CronTime('0,10 0,10 * * * *');
  69. }).not.toThrow();
  70. });
  71. it('should test all commas (0,10 0,10 1,10 1,10 0,6 0,1)', function() {
  72. expect(function() {
  73. new cron.CronTime('0,10 0,10 1,10 1,10 0,6 0,1');
  74. }).not.toThrow();
  75. });
  76. it('should test alias (* * * * jan *)', function() {
  77. expect(function() {
  78. new cron.CronTime('* * * * jan *');
  79. }).not.toThrow();
  80. });
  81. it('should test multi aliases (* * * * jan,feb *)', function() {
  82. expect(function() {
  83. new cron.CronTime('* * * * jan,feb *');
  84. }).not.toThrow();
  85. });
  86. it('should test all aliases (* * * * jan,feb mon,tue)', function() {
  87. expect(function() {
  88. new cron.CronTime('* * * * jan,feb mon,tue');
  89. }).not.toThrow();
  90. });
  91. it('should test unknown alias (* * * * jar *)', function() {
  92. expect(function() {
  93. new cron.CronTime('* * * * jar *');
  94. }).toThrow();
  95. });
  96. it('should test unknown alias - short (* * * * j *)', function() {
  97. expect(function() {
  98. new cron.CronTime('* * * * j *');
  99. }).toThrow();
  100. });
  101. it('should test too few fields', function() {
  102. expect(function() {
  103. new cron.CronTime('* * * *', null, null);
  104. }).toThrow();
  105. });
  106. it('should test too many fields', function() {
  107. expect(function() {
  108. new cron.CronTime('* * * * * * *', null, null);
  109. }).toThrow();
  110. });
  111. it('should test out of range values', function() {
  112. expect(function() {
  113. new cron.CronTime('* * * * 1234', null, null);
  114. }).toThrow();
  115. });
  116. it('should test invalid wildcard expression', function() {
  117. expect(function() {
  118. new cron.CronTime('* * * * 0*');
  119. }).toThrow();
  120. });
  121. it('should test invalid step', function() {
  122. expect(function() {
  123. new cron.CronTime('* * * 1/0 *');
  124. }).toThrow();
  125. });
  126. it('should test invalid range', function() {
  127. expect(function() {
  128. new cron.CronTime('* 2-1 * * *');
  129. }).toThrow();
  130. });
  131. it('should test Date', function() {
  132. const d = new Date();
  133. const ct = new cron.CronTime(d);
  134. expect(ct.source.isSame(d.getTime())).toBe(true);
  135. });
  136. it('should test day roll-over', function() {
  137. const numHours = 24;
  138. const ct = new cron.CronTime('0 0 17 * * *');
  139. for (let hr = 0; hr < numHours; hr++) {
  140. const start = new Date(2012, 3, 16, hr, 30, 30);
  141. const next = ct._getNextDateFrom(start);
  142. expect(next - start).toBeLessThan(24 * 60 * 60 * 1000);
  143. expect(next._d.getTime()).toBeGreaterThan(start.getTime());
  144. }
  145. });
  146. it('should test illegal repetition syntax', function() {
  147. expect(function() {
  148. new cron.CronTime('* * /4 * * *');
  149. }).toThrow();
  150. });
  151. it('should test next date', function() {
  152. const ct = new cron.CronTime('0 0 */4 * * *');
  153. const nextDate = new Date();
  154. nextDate.setHours(23);
  155. const nextdt = ct._getNextDateFrom(nextDate);
  156. expect(nextdt._d.getTime()).toBeGreaterThan(nextDate.getTime());
  157. expect(nextdt.hours() % 4).toEqual(0);
  158. });
  159. it('should throw an exception because next date is invalid', function() {
  160. const ct = new cron.CronTime('0 0 * * * *');
  161. const nextDate = new Date('My invalid date string');
  162. try {
  163. // eslint-disable-next-line no-unused-vars
  164. const nextdt = ct._getNextDateFrom(nextDate);
  165. } catch (e) {
  166. expect(e.message).toEqual('ERROR: You specified an invalid date.');
  167. }
  168. });
  169. it('should test next real date', function() {
  170. const initialDate = new Date();
  171. const ct = new cron.CronTime(initialDate);
  172. const nextDate = new Date();
  173. nextDate.setMonth(nextDate.getMonth() + 1);
  174. expect(nextDate.getTime()).toBeGreaterThan(ct.source._d.getTime());
  175. const nextdt = ct.sendAt(0);
  176. // there shouldn't be a "next date" when using a real date.
  177. // execution happens once
  178. // so the return should be the date passed in unless explicitly reset
  179. expect(nextdt.isBefore(nextDate)).toBeTruthy();
  180. expect(nextdt.isSame(initialDate)).toBeTruthy();
  181. });
  182. describe('should throw an exception because `L` not supported', function() {
  183. it('(* * * L * *)', function() {
  184. expect(function() {
  185. new cron.CronTime('* * * L * *');
  186. }).toThrow();
  187. });
  188. it('(* * * * * L)', function() {
  189. expect(function() {
  190. new cron.CronTime('* * * * * L');
  191. }).toThrow();
  192. });
  193. });
  194. it('should strip off millisecond', function() {
  195. const cronTime = new cron.CronTime('0 */10 * * * *');
  196. const x = cronTime._getNextDateFrom(new Date('2018-08-10T02:20:00.999Z'));
  197. expect(x.toISOString()).toEqual('2018-08-10T02:30:00.000Z');
  198. });
  199. it('should strip off millisecond (2)', function() {
  200. const cronTime = new cron.CronTime('0 */10 * * * *');
  201. const x = cronTime._getNextDateFrom(new Date('2018-08-10T02:19:59.999Z'));
  202. expect(x.toISOString()).toEqual('2018-08-10T02:20:00.000Z');
  203. });
  204. it('should generete the right next days when cron is set to every minute', function() {
  205. const cronTime = new cron.CronTime('* * * * *');
  206. const min = 60000;
  207. let previousDate = new Date(Date.UTC(2018, 5, 3, 0, 0));
  208. for (let i = 0; i < 25; i++) {
  209. const nextDate = cronTime._getNextDateFrom(previousDate);
  210. expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min);
  211. previousDate = nextDate;
  212. }
  213. });
  214. it('should generete the right next days when cron is set to every 15 min', function() {
  215. const cronTime = new cron.CronTime('*/15 * * * *');
  216. const min = 60000 * 15;
  217. let previousDate = new Date(Date.UTC(2016, 6, 3, 0, 0));
  218. for (let i = 0; i < 25; i++) {
  219. const nextDate = cronTime._getNextDateFrom(previousDate);
  220. expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min);
  221. previousDate = nextDate;
  222. }
  223. });
  224. it('should work around time zone changes that shifts time back (1)', function() {
  225. const d = new Date('10-7-2018');
  226. // America/Sao_Paulo has a time zone change around NOV 3 2018.
  227. const cronTime = new cron.CronTime('0 0 9 4 * *');
  228. const nextDate = cronTime._getNextDateFrom(d, 'America/Sao_Paulo');
  229. expect(nextDate.valueOf()).toEqual(
  230. moment('2018-11-04T09:00:00.000-02:00').valueOf()
  231. );
  232. });
  233. it('should work around time zone changes that shifts time back (2)', function() {
  234. // Asia/Amman DST ends in 26 - OCT-2018 (-1 to hours)
  235. const d = moment.tz('2018-10-25T23:00', 'Asia/Amman');
  236. const cronTime = new cron.CronTime('0 0 * * *');
  237. const nextDate = cronTime._getNextDateFrom(d, 'Asia/Amman');
  238. expect(nextDate - moment.tz('2018-10-26T00:00', 'Asia/Amman')).toEqual(0);
  239. });
  240. it('should work around time zone changes that shifts time forward', function() {
  241. // Asia/Amman DST starts in 30-March-2018 (+1 to hours)
  242. let currentDate = moment.tz('2018-03-29T23:00', 'Asia/Amman');
  243. const cronTime = new cron.CronTime('* * * * *');
  244. for (let i = 0; i < 100; i++) {
  245. const nextDate = cronTime._getNextDateFrom(currentDate, 'Asia/Amman');
  246. expect(nextDate - currentDate).toEqual(1000 * 60);
  247. currentDate = nextDate;
  248. }
  249. });
  250. it('should generate the right N next days for * * * * *', function() {
  251. const cronTime = new cron.CronTime('* * * * *');
  252. let currentDate = moment()
  253. .seconds(0)
  254. .milliseconds(0);
  255. for (let i = 0; i < 100; i++) {
  256. const nextDate = cronTime._getNextDateFrom(currentDate);
  257. expect(nextDate - currentDate).toEqual(1000 * 60);
  258. currentDate = nextDate;
  259. }
  260. });
  261. it('should generate the right N next days for 0 0 9 * * *', function() {
  262. const cronTime = new cron.CronTime('0 0 9 * * *');
  263. let currentDate = moment()
  264. .utc()
  265. .seconds(0)
  266. .milliseconds(0)
  267. .hours(9)
  268. .minutes(0);
  269. for (let i = 0; i < 100; i++) {
  270. const nextDate = cronTime._getNextDateFrom(currentDate);
  271. expect(nextDate - currentDate).toEqual(1000 * 60 * 60 * 24);
  272. currentDate = nextDate;
  273. }
  274. });
  275. it('should generate the right N next days for 0 0 * * * with a time zone', function() {
  276. const cronTime = new cron.CronTime('0 * * * *');
  277. let currentDate = moment
  278. .tz('2018-11-02T23:00', 'America/Sao_Paulo')
  279. .seconds(0)
  280. .milliseconds(0);
  281. for (let i = 0; i < 25; i++) {
  282. const nextDate = cronTime._getNextDateFrom(
  283. currentDate,
  284. 'America/Sao_Paulo'
  285. );
  286. expect(nextDate - currentDate).toEqual(1000 * 60 * 60);
  287. currentDate = nextDate;
  288. }
  289. });
  290. it('should generate the right N next days for */3 * * * * with a time zone', function() {
  291. const cronTime = new cron.CronTime('*/3 * * * *');
  292. let currentDate = moment
  293. .tz('2018-11-02T23:00', 'America/Sao_Paulo')
  294. .seconds(0)
  295. .milliseconds(0);
  296. for (let i = 0; i < 25; i++) {
  297. const nextDate = cronTime._getNextDateFrom(
  298. currentDate,
  299. 'America/Sao_Paulo'
  300. );
  301. expect(nextDate - currentDate).toEqual(1000 * 60 * 3);
  302. currentDate = nextDate;
  303. }
  304. });
  305. it('should generete the right next day when cron is set to every 15 min in Feb', function() {
  306. const cronTime = new cron.CronTime('*/15 * * FEB *');
  307. const previousDate = new Date(Date.UTC(2018, 3, 0, 0, 0));
  308. const nextDate = cronTime._getNextDateFrom(previousDate, 'UTC');
  309. expect(nextDate.valueOf()).toEqual(
  310. new Date(Date.UTC(2019, 1, 1, 0, 0)).valueOf()
  311. );
  312. });
  313. it('should generate the right next day when cron is set to both day of the month and day of the week (1)', function() {
  314. const cronTime = new cron.CronTime('0 8 1 * 4');
  315. const previousDate = new Date(Date.UTC(2019, 3, 22, 0, 0));
  316. const nextDate = cronTime._getNextDateFrom(previousDate, 'UTC');
  317. expect(nextDate.valueOf()).toEqual(
  318. new Date(Date.UTC(2019, 3, 25, 8, 0)).valueOf()
  319. );
  320. });
  321. it('should generate the right next day when cron is set to both day of the month and day of the week (2)', function() {
  322. const cronTime = new cron.CronTime('0 8 1 * 4');
  323. const previousDate = new Date(Date.UTC(2019, 3, 26, 0, 0));
  324. const nextDate = cronTime._getNextDateFrom(previousDate, 'UTC');
  325. expect(nextDate.valueOf()).toEqual(
  326. new Date(Date.UTC(2019, 4, 1, 8, 0)).valueOf()
  327. );
  328. });
  329. it('should generate the right next day when cron is set to both day of the month and day of the week (3)', function() {
  330. const cronTime = new cron.CronTime('0 8 1 * 4');
  331. const previousDate = new Date(Date.UTC(2019, 7, 1, 7, 59));
  332. const nextDate = cronTime._getNextDateFrom(previousDate, 'UTC');
  333. expect(nextDate.valueOf()).toEqual(
  334. new Date(Date.UTC(2019, 7, 1, 8, 0)).valueOf()
  335. );
  336. });
  337. it('should accept 0 as a valid UTC offset', function() {
  338. const clock = sinon.useFakeTimers();
  339. const cronTime = new cron.CronTime('0 11 * * *', null, 0);
  340. const expected = moment()
  341. .add(11, 'hours')
  342. .unix();
  343. const actual = cronTime.sendAt().unix();
  344. expect(actual).toEqual(expected);
  345. clock.restore();
  346. });
  347. it('should accept -120 as a valid UTC offset', function() {
  348. const clock = sinon.useFakeTimers();
  349. const cronTime = new cron.CronTime('0 11 * * *', null, -120);
  350. const expected = moment()
  351. .add(13, 'hours')
  352. .unix();
  353. const actual = cronTime.sendAt().unix();
  354. expect(actual).toEqual(expected);
  355. clock.restore();
  356. });
  357. });