stacks 0.58.63 → 0.58.64

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.
Files changed (138) hide show
  1. package/core/actions/dist/src/database/seed.js +0 -3
  2. package/core/actions/dist/src/deploy/index.js +1 -1
  3. package/core/actions/dist/src/index.js +3 -0
  4. package/core/actions/dist/src/release.js +5 -2
  5. package/core/actions/dist/src/upgrade.js +1 -1
  6. package/core/actions/package.json +1 -1
  7. package/core/actions/src/action.ts +4 -1
  8. package/core/actions/src/copy-types.ts +1 -1
  9. package/core/actions/src/database/seed.ts +3 -3
  10. package/core/actions/src/deploy/index.ts +1 -1
  11. package/core/actions/src/helpers/utils.ts +2 -2
  12. package/core/ai/package.json +1 -1
  13. package/core/alias/package.json +1 -1
  14. package/core/analytics/package.json +1 -1
  15. package/core/api/package.json +1 -1
  16. package/core/arrays/package.json +1 -1
  17. package/core/arrays/src/helpers.ts +3 -3
  18. package/core/auth/package.json +1 -1
  19. package/core/buddy/dist/cli.js +1 -1
  20. package/core/buddy/package.json +1 -1
  21. package/core/buddy/src/cli.ts +1 -1
  22. package/core/build/package.json +1 -1
  23. package/core/bun-create/bud/package.json +1 -1
  24. package/core/bun-create/buddy/package.json +1 -1
  25. package/core/bun-create/stack/package.json +1 -1
  26. package/core/bun-create/stacks/package.json +1 -1
  27. package/core/bun-create/stx/package.json +1 -1
  28. package/core/bun-plugin-yaml/package.json +1 -1
  29. package/core/cache/package.json +1 -1
  30. package/core/cache/tests/DynamoDB.test.ts +125 -125
  31. package/core/cache/tests/Memcached.test.ts +51 -51
  32. package/core/cache/tests/Redis.test.ts +84 -84
  33. package/core/chat/package.json +1 -1
  34. package/core/cli/dist/index.js +1 -1
  35. package/core/cli/package.json +1 -1
  36. package/core/cli/src/exec.ts +2 -2
  37. package/core/cloud/dist/index.js +7 -7
  38. package/core/cloud/package.json +1 -1
  39. package/core/cloud/src/cloud/ai.ts +3 -3
  40. package/core/cloud/src/cloud/aws-sdk-layer/nodejs/package.json +1 -1
  41. package/core/cloud/src/cloud/cli.ts +1 -1
  42. package/core/cloud/src/cloud/deployment.ts +3 -3
  43. package/core/cloud/src/cloud/router-layer/nodejs/package.json +2 -2
  44. package/core/collections/package.json +1 -1
  45. package/core/config/dist/index.js +4 -0
  46. package/core/config/package.json +1 -1
  47. package/core/database/package.json +1 -1
  48. package/core/database/src/kysely-bun-worker/driver.ts +1 -1
  49. package/core/datetime/package.json +1 -1
  50. package/core/desktop/package.json +1 -1
  51. package/core/development/package.json +1 -1
  52. package/core/dns/package.json +1 -1
  53. package/core/docs/package.json +1 -1
  54. package/core/email/package.json +2 -2
  55. package/core/enums/package.json +1 -1
  56. package/core/env/package.json +1 -1
  57. package/core/error-handling/package.json +1 -1
  58. package/core/error-handling/src/handler.ts +1 -1
  59. package/core/eslint-config/package.json +1 -1
  60. package/core/events/package.json +1 -1
  61. package/core/faker/package.json +1 -1
  62. package/core/git/package.json +1 -1
  63. package/core/health/package.json +1 -1
  64. package/core/http/package.json +1 -1
  65. package/core/lint/package.json +1 -1
  66. package/core/logging/package.json +1 -1
  67. package/core/notifications/package.json +1 -1
  68. package/core/objects/package.json +1 -1
  69. package/core/orm/package.json +1 -1
  70. package/core/path/dist/index.js +30 -0
  71. package/core/path/package.json +1 -1
  72. package/core/path/src/index.ts +30 -0
  73. package/core/payments/package.json +1 -1
  74. package/core/push/package.json +1 -1
  75. package/core/query-builder/package.json +1 -1
  76. package/core/queue/package.json +1 -1
  77. package/core/raycast/package.json +1 -1
  78. package/core/realtime/package.json +1 -1
  79. package/core/repl/package.json +1 -1
  80. package/core/router/dist/index.js +40 -2
  81. package/core/router/package.json +1 -1
  82. package/core/router/src/router.ts +21 -1
  83. package/core/router/src/server.ts +0 -2
  84. package/core/scheduler/dist/index.js +1 -2
  85. package/core/scheduler/package.json +2 -1
  86. package/core/scheduler/src/index.ts +1 -1
  87. package/core/scheduler/src/job.ts +2 -2
  88. package/core/scheduler/src/schedule.ts +2 -2
  89. package/core/scheduler/tests/cron.test.ts +1243 -1243
  90. package/core/scheduler/tests/crontime.test.ts +780 -778
  91. package/core/search-engine/dist/index.js +1 -3
  92. package/core/search-engine/package.json +1 -1
  93. package/core/search-engine/src/index.ts +5 -5
  94. package/core/security/package.json +1 -1
  95. package/core/server/package.json +1 -1
  96. package/core/signals/package.json +1 -1
  97. package/core/slug/package.json +1 -1
  98. package/core/sms/package.json +1 -1
  99. package/core/storage/dist/index.js +0 -1
  100. package/core/storage/package.json +1 -1
  101. package/core/storage/src/files.ts +2 -5
  102. package/core/storage/src/hash.ts +0 -2
  103. package/core/strings/package.json +1 -1
  104. package/core/tables/package.json +1 -1
  105. package/core/testing/dist/index.js +14978 -1
  106. package/core/testing/package.json +1 -1
  107. package/core/testing/src/index.ts +12 -2
  108. package/core/tinker/package.json +1 -1
  109. package/core/tunnel/package.json +1 -1
  110. package/core/types/package.json +1 -1
  111. package/core/types/src/cli.ts +1 -1
  112. package/core/types/src/cron-jobs.ts +0 -5
  113. package/core/types/src/errors.ts +1 -1
  114. package/core/types/src/router.ts +7 -5
  115. package/core/ui/package.json +1 -1
  116. package/core/utils/dist/index.js +4 -8
  117. package/core/utils/package.json +1 -1
  118. package/core/utils/scripts/export-size.ts +3 -3
  119. package/core/utils/src/base.ts +4 -4
  120. package/core/utils/src/helpers.ts +3 -3
  121. package/core/utils/src/retry.ts +2 -2
  122. package/core/validation/package.json +1 -1
  123. package/core/vite/dist/index.js +1 -1
  124. package/core/vite/package.json +1 -1
  125. package/core/vite/src/functions.ts +0 -1
  126. package/core/vite/src/index.ts +1 -1
  127. package/core/vite/src/plugin/docs.ts +2 -0
  128. package/core/vite/src/plugin/stacks.ts +3 -2
  129. package/core/vite/src/web-components.ts +2 -2
  130. package/core/whois/package.json +1 -1
  131. package/core/whois/src/index.ts +2 -2
  132. package/core/x-ray/package.json +1 -1
  133. package/core/zsh-buddy/package.json +1 -1
  134. package/ide/vscode/package.json +1 -1
  135. package/package.json +1 -1
  136. package/core/actions/src/database/mydb.sqlite +0 -0
  137. package/core/actions/src/database/stacks.sqlite +0 -0
  138. package/core/server/src/api.ts +0 -5
@@ -1,778 +1,780 @@
1
- /* eslint-disable no-new */
2
- import { DateTime } from 'luxon'
3
- import sinon from 'sinon'
4
- import { CronTime } from '../src'
5
-
6
- describe('crontime', () => {
7
- afterEach(() => expect.hasAssertions())
8
-
9
- it('should test stars (* * * * * *)', () => {
10
- expect(() => {
11
- new CronTime('* * * * * *')
12
- }).not.toThrow()
13
- })
14
-
15
- it('should test digit (0 * * * * *)', () => {
16
- expect(() => {
17
- new CronTime('0 * * * * *')
18
- }).not.toThrow()
19
- })
20
-
21
- it('should test multi digits (08 * * * * *)', () => {
22
- expect(() => {
23
- new CronTime('08 * * * * *')
24
- }).not.toThrow()
25
- })
26
-
27
- it('should test all digits (08 8 8 8 8 5)', () => {
28
- expect(() => {
29
- new CronTime('08 * * * * *')
30
- }).not.toThrow()
31
- })
32
-
33
- it('should test too many digits (08 8 8 8 8 5)', () => {
34
- expect(() => {
35
- new CronTime('08 * * * * *')
36
- }).not.toThrow()
37
- })
38
-
39
- it('should test standard cron format (* * * * *)', () => {
40
- expect(() => {
41
- new CronTime('* * * * *')
42
- }).not.toThrow()
43
- })
44
-
45
- it('should test standard cron format (8 8 8 8 5)', () => {
46
- const standard = new CronTime('8 8 8 8 5')
47
- const extended = new CronTime('0 8 8 8 8 5')
48
-
49
- // @ts-expect-error deleting for comparaison purposes
50
- delete standard.source
51
- // @ts-expect-error deleting for comparaison purposes
52
- delete extended.source
53
-
54
- expect(extended).toEqual(standard)
55
- })
56
-
57
- it('should test hyphen (0-10 * * * * *)', () => {
58
- expect(() => {
59
- new CronTime('0-10 * * * * *')
60
- }).not.toThrow()
61
- })
62
-
63
- it('should test multi hyphens (0-10 0-10 * * * *)', () => {
64
- expect(() => {
65
- new CronTime('0-10 0-10 * * * *')
66
- }).not.toThrow()
67
- })
68
-
69
- it('should test all hyphens (0-10 0-10 1-10 1-10 1-7 0-1)', () => {
70
- expect(() => {
71
- new CronTime('0-10 0-10 1-10 1-10 1-7 0-1')
72
- }).not.toThrow()
73
- })
74
-
75
- it('should accept all valid ranges (0-59 0-59 0-23 1-31 1-12 0-7)', () => {
76
- expect(() => {
77
- new CronTime('0-59 0-59 0-23 1-31 1-12 0-7')
78
- }).not.toThrow()
79
- })
80
-
81
- it('should test comma (0,10 * * * * *)', () => {
82
- expect(() => {
83
- new CronTime('0,10 * * * * *')
84
- }).not.toThrow()
85
- })
86
-
87
- it('should test multi commas (0,10 0,10 * * * *)', () => {
88
- expect(() => {
89
- new CronTime('0,10 0,10 * * * *')
90
- }).not.toThrow()
91
- })
92
-
93
- it('should test all commas (0,10 0,10 1,10 1,10 1,7 0,1)', () => {
94
- expect(() => {
95
- new CronTime('0,10 0,10 1,10 1,10 1,7 0,1')
96
- }).not.toThrow()
97
- })
98
-
99
- it('should test alias (* * * * jan *)', () => {
100
- expect(() => {
101
- new CronTime('* * * * jan *')
102
- }).not.toThrow()
103
- })
104
-
105
- it('should test multi aliases (* * * * jan,feb *)', () => {
106
- expect(() => {
107
- new CronTime('* * * * jan,feb *')
108
- }).not.toThrow()
109
- })
110
-
111
- it('should test all aliases (* * * * jan,feb mon,tue)', () => {
112
- expect(() => {
113
- new CronTime('* * * * jan,feb mon,tue')
114
- }).not.toThrow()
115
- })
116
-
117
- it('should test unknown alias (* * * * jar *)', () => {
118
- expect(() => {
119
- new CronTime('* * * * jar *')
120
- }).toThrow()
121
- })
122
-
123
- it('should test unknown alias - short (* * * * j *)', () => {
124
- expect(() => {
125
- new CronTime('* * * * j *')
126
- }).toThrow()
127
- })
128
-
129
- it('should be case-insensitive for aliases (* * * * JAN,FEB MON,TUE)', () => {
130
- expect(() => {
131
- new CronTime('* * * * JAN,FEB MON,TUE', null, null)
132
- }).not.toThrow()
133
- })
134
-
135
- it('should test too few fields', () => {
136
- expect(() => {
137
- new CronTime('* * * *', null, null)
138
- }).toThrow()
139
- })
140
-
141
- it('should test too many fields', () => {
142
- expect(() => {
143
- new CronTime('* * * * * * *', null, null)
144
- }).toThrow()
145
- })
146
-
147
- it('should return the same object with 0 & 7 as Sunday (except "source" prop)', () => {
148
- const sunday0 = new CronTime('* * * * 0', null, null)
149
- const sunday7 = new CronTime('* * * * 7', null, null)
150
-
151
- // @ts-expect-error deleting for comparaison purposes
152
- delete sunday0.source
153
- // @ts-expect-error deleting for comparaison purposes
154
- delete sunday7.source
155
-
156
- expect(sunday7).toEqual(sunday0)
157
- })
158
-
159
- describe('should test out of range values', () => {
160
- it('should test out of range minute', () => {
161
- expect(() => {
162
- new CronTime('-1 * * * *', null, null)
163
- }).toThrow()
164
- expect(() => {
165
- new CronTime('60 * * * *', null, null)
166
- }).toThrow()
167
- })
168
-
169
- it('should test out of range hour', () => {
170
- expect(() => {
171
- new CronTime('* -1 * * *', null, null)
172
- }).toThrow()
173
- expect(() => {
174
- new CronTime('* 24 * * *', null, null)
175
- }).toThrow()
176
- })
177
-
178
- it('should test out of range day-of-month', () => {
179
- expect(() => {
180
- new CronTime('* * 0 * *', null, null)
181
- }).toThrow()
182
- expect(() => {
183
- new CronTime('* * 32 * *', null, null)
184
- }).toThrow()
185
- })
186
-
187
- it('should test out of range month', () => {
188
- expect(() => {
189
- new CronTime('* * * 0 *', null, null)
190
- }).toThrow()
191
- expect(() => {
192
- new CronTime('* * * 13 *', null, null)
193
- }).toThrow()
194
- })
195
-
196
- it('should test out of range day-of-week', () => {
197
- expect(() => {
198
- new CronTime('* * * * -1', null, null)
199
- }).toThrow()
200
- expect(() => {
201
- new CronTime('* * * * 8', null, null)
202
- }).toThrow()
203
- })
204
- })
205
-
206
- it('should test invalid wildcard expression', () => {
207
- expect(() => {
208
- new CronTime('* * * * 0*')
209
- }).toThrow()
210
- })
211
-
212
- it('should test invalid step', () => {
213
- expect(() => {
214
- new CronTime('* * * 1/ *')
215
- }).toThrow()
216
-
217
- expect(() => {
218
- new CronTime('* * * 1/0 *')
219
- }).toThrow()
220
-
221
- expect(() => {
222
- new CronTime('* * * 1/00 *')
223
- }).toThrow()
224
- })
225
-
226
- it('should test invalid range', () => {
227
- expect(() => {
228
- new CronTime('* 2-1 * * *')
229
- }).toThrow()
230
-
231
- expect(() => {
232
- new CronTime('* 2-0 * * *')
233
- }).toThrow()
234
-
235
- expect(() => {
236
- new CronTime('* 2- * * *')
237
- }).toThrow()
238
- })
239
-
240
- it('should test Date', () => {
241
- const d = new Date()
242
- const ct = new CronTime(d)
243
- expect(ct.source).toBeInstanceOf(DateTime)
244
- expect((ct.source as DateTime).toMillis()).toEqual(d.getTime())
245
- })
246
-
247
- it('should test day roll-over', () => {
248
- const numHours = 24
249
- const ct = new CronTime('0 0 17 * * *')
250
-
251
- for (let hr = 0; hr < numHours; hr++) {
252
- const start = new Date(2012, 3, 16, hr, 30, 30)
253
- const next = ct.getNextDateFrom(start)
254
- expect(next.toMillis() - start.getTime()).toBeLessThan(
255
- 24 * 60 * 60 * 1000,
256
- )
257
- expect(next.toMillis()).toBeGreaterThan(start.getTime())
258
- }
259
- })
260
-
261
- it('should test illegal repetition syntax', () => {
262
- expect(() => {
263
- new CronTime('* * /4 * * *')
264
- }).toThrow()
265
- })
266
-
267
- it('should test next date', () => {
268
- const ct = new CronTime('0 0 */4 * * *')
269
-
270
- const nextDate = new Date()
271
- nextDate.setHours(23)
272
- const nextdt = ct.getNextDateFrom(nextDate)
273
-
274
- expect(nextdt.toMillis()).toBeGreaterThan(nextDate.getTime())
275
- expect(nextdt.hour % 4).toBe(0)
276
- })
277
-
278
- it('should throw an exception because next date is invalid', () => {
279
- const ct = new CronTime('0 0 * * * *')
280
- const nextDate = new Date('My invalid date string')
281
-
282
- expect(() => {
283
- ct.getNextDateFrom(nextDate)
284
- }).toThrow('ERROR: You specified an invalid date.')
285
- })
286
-
287
- it('should test next real date', () => {
288
- const initialDate = new Date()
289
- initialDate.setDate(initialDate.getDate() + 1) // In other case date will be in the past
290
- const ct = new CronTime(initialDate)
291
-
292
- const nextDate = new Date()
293
- nextDate.setMonth(nextDate.getMonth() + 1)
294
- expect(ct.source).toBeInstanceOf(DateTime)
295
- expect(nextDate.getTime()).toBeGreaterThan(
296
- (ct.source as DateTime).toMillis(),
297
- )
298
- const nextDt = ct.sendAt()
299
- // there shouldn't be a "next date" when using a real date.
300
- // execution happens once
301
- // so the return should be the date passed in unless explicitly reset
302
- expect(nextDt.toMillis() < nextDate.getTime()).toBeTruthy()
303
- expect(nextDt.toMillis()).toEqual(initialDate.getTime())
304
- })
305
-
306
- describe('presets', () => {
307
- it('should parse @secondly', () => {
308
- const cronTime = new CronTime('@secondly')
309
- expect(cronTime.toString()).toBe('* * * * * *')
310
- })
311
-
312
- it('should parse @minutely', () => {
313
- const cronTime = new CronTime('@minutely')
314
- expect(cronTime.toString()).toBe('0 * * * * *')
315
- })
316
-
317
- it('should parse @hourly', () => {
318
- const cronTime = new CronTime('@hourly')
319
- expect(cronTime.toString()).toBe('0 0 * * * *')
320
- })
321
-
322
- it('should parse @daily', () => {
323
- const cronTime = new CronTime('@daily')
324
- expect(cronTime.toString()).toBe('0 0 0 * * *')
325
- })
326
-
327
- it('should parse @weekly', () => {
328
- const cronTime = new CronTime('@weekly')
329
- expect(cronTime.toString()).toBe('0 0 0 * * 0')
330
- })
331
-
332
- it('should parse @weekdays', () => {
333
- const cronTime = new CronTime('@weekdays')
334
- expect(cronTime.toString()).toBe('0 0 0 * * 1,2,3,4,5')
335
- })
336
-
337
- it('should parse @weekends', () => {
338
- const cronTime = new CronTime('@weekends')
339
- expect(cronTime.toString()).toBe('0 0 0 * * 0,6')
340
- })
341
-
342
- it('should parse @monthly', () => {
343
- const cronTime = new CronTime('@monthly')
344
- expect(cronTime.toString()).toBe('0 0 0 1 * *')
345
- })
346
-
347
- it('should parse @yearly', () => {
348
- const cronTime = new CronTime('@yearly')
349
- expect(cronTime.toString()).toBe('0 0 0 1 1 *')
350
- })
351
- })
352
-
353
- describe('should throw an exception because `L` not supported', () => {
354
- it('(* * * L * *)', () => {
355
- expect(() => {
356
- new CronTime('* * * L * *')
357
- }).toThrow()
358
- })
359
-
360
- it('(* * * * * L)', () => {
361
- expect(() => {
362
- new CronTime('* * * * * L')
363
- }).toThrow()
364
- })
365
- })
366
-
367
- it('should strip off millisecond', () => {
368
- const cronTime = new CronTime('0 */10 * * * *')
369
- const x = cronTime.getNextDateFrom(new Date('2018-08-10T02:20:00.999Z'))
370
- expect(x.toMillis()).toEqual(
371
- new Date('2018-08-10T02:30:00.000Z').getTime(),
372
- )
373
- })
374
-
375
- it('should strip off millisecond (2)', () => {
376
- const cronTime = new CronTime('0 */10 * * * *')
377
- const x = cronTime.getNextDateFrom(new Date('2018-08-10T02:19:59.999Z'))
378
- expect(x.toMillis()).toEqual(
379
- new Date('2018-08-10T02:20:00.000Z').getTime(),
380
- )
381
- })
382
-
383
- it('should expose getNextDateFrom as a public function', () => {
384
- const cronTime = new CronTime('0 */10 * * * *')
385
- cronTime.getNextDateFrom = jest.fn()
386
-
387
- const testDate = new Date('2018-08-10T02:19:59.999Z')
388
- const testTimezone = 'Asia/Amman'
389
- cronTime.getNextDateFrom(testDate, testTimezone)
390
-
391
- expect(cronTime.getNextDateFrom).toHaveBeenCalledWith(
392
- testDate,
393
- testTimezone,
394
- )
395
- })
396
-
397
- it('should generate the right next days when cron is set to every minute', () => {
398
- const cronTime = new CronTime('* * * * *')
399
- const min = 60000
400
- let previousDate = DateTime.fromMillis(Date.UTC(2018, 5, 3, 0, 0))
401
- for (let i = 0; i < 25; i++) {
402
- const nextDate = cronTime.getNextDateFrom(previousDate)
403
- expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min)
404
- previousDate = nextDate
405
- }
406
- })
407
-
408
- it('should generate the right next days when cron is set to every 15 min', () => {
409
- const cronTime = new CronTime('*/15 * * * *')
410
- const min = 60000 * 15
411
- let previousDate = DateTime.fromMillis(Date.UTC(2016, 6, 3, 0, 0))
412
- for (let i = 0; i < 25; i++) {
413
- const nextDate = cronTime.getNextDateFrom(previousDate)
414
- expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min)
415
- previousDate = nextDate
416
- }
417
- })
418
- it('should work around time zone changes that shifts time back (1)', () => {
419
- const d = new Date('10-7-2018')
420
- // America/Sao_Paulo has a time zone change around NOV 3 2018.
421
- const cronTime = new CronTime('0 0 9 4 * *')
422
- const nextDate = cronTime.getNextDateFrom(d, 'America/Sao_Paulo')
423
- expect(nextDate.valueOf()).toEqual(
424
- DateTime.fromISO('2018-11-04T09:00:00.000-02:00').valueOf(),
425
- )
426
- })
427
- it('should work around time zone changes that shifts time back (2)', () => {
428
- // Asia/Amman DST ends in 26 - OCT-2018 (-1 to hours)
429
- const currentDate = DateTime.fromISO('2018-10-25T23:00', {
430
- zone: 'Asia/Amman',
431
- })
432
- const cronTime = new CronTime('0 0 * * *')
433
- const nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
434
- const expectedDate = DateTime.fromISO('2018-10-26T00:00+03:00', {
435
- zone: 'Asia/Amman',
436
- })
437
- expect(nextDate.toMillis() - expectedDate.toMillis()).toBe(0)
438
- })
439
- it('should work around time zone changes that shifts time forward', () => {
440
- // Asia/Amman DST starts in 30-March-2018 (+1 to hours)
441
- let currentDate = DateTime.fromISO('2018-03-29T23:00', {
442
- zone: 'Asia/Amman',
443
- })
444
- const cronTime = new CronTime('* * * * *')
445
- for (let i = 0; i < 100; i++) {
446
- const nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
447
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
448
- currentDate = nextDate
449
- }
450
- })
451
- it('should schedule jobs inside time zone changes that shifts time forward to the end of the shift, for weekly jobs', () => {
452
- let currentDate = DateTime.fromISO('2018-03-29T23:15', {
453
- zone: 'Asia/Amman',
454
- })
455
- const cronTime = new CronTime('30 0 * * 5') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
456
- let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
457
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
458
- 1000 * 60 * 45,
459
- ) // 45 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
460
- // the next one should just be at 0:30 again. i.e. a week minus 30 minutes.
461
- currentDate = nextDate
462
- nextDate = cronTime.getNextDateFrom(currentDate)
463
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
464
- 3600000 * 24 * 7 - 60000 * 30,
465
- )
466
- // the next one is again at 0:30, but now we're 'back to normal' with weekly offsets.
467
- currentDate = nextDate
468
- nextDate = cronTime.getNextDateFrom(currentDate)
469
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
470
- 1000 * 3600 * 24 * 7,
471
- )
472
- })
473
- it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for daily jobs', () => {
474
- let currentDate = DateTime.fromISO('2018-03-29T23:45', {
475
- zone: 'Asia/Amman',
476
- })
477
- const cronTime = new CronTime('30 0 * * *') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
478
- let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
479
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
480
- 1000 * 60 * 15,
481
- ) // 15 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
482
- // the next one is tomorrow at 0:30, so 23h30m.
483
- currentDate = nextDate
484
- nextDate = cronTime.getNextDateFrom(currentDate)
485
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
486
- 1000 * 3600 * 24 - 1000 * 60 * 30,
487
- )
488
- // back to normal.
489
- currentDate = nextDate
490
- nextDate = cronTime.getNextDateFrom(currentDate)
491
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
492
- 1000 * 3600 * 24,
493
- )
494
- })
495
- it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for hourly jobs', () => {
496
- let currentDate = DateTime.fromISO('2018-03-29T23:45', {
497
- zone: 'Asia/Amman',
498
- })
499
- const cronTime = new CronTime('30 * * * *') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
500
- let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
501
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
502
- 1000 * 60 * 15,
503
- ) // 15 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
504
- // the next one is at 1:30, so 30m.
505
- currentDate = nextDate
506
- nextDate = cronTime.getNextDateFrom(currentDate)
507
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
508
- 1000 * 60 * 30,
509
- )
510
- // back to normal.
511
- currentDate = nextDate
512
- nextDate = cronTime.getNextDateFrom(currentDate)
513
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 3600)
514
- })
515
- it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for minutely jobs', () => {
516
- let currentDate = DateTime.fromISO('2018-03-29T23:59', {
517
- zone: 'Asia/Amman',
518
- })
519
- const cronTime = new CronTime('* * * * *') // the next minute is 0:00 is March 30th, but it will jump from 0:00 to 1:00.
520
- let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
521
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
522
- // the next one is at 1:01:00, this should still be 60 seconds in the future.
523
- currentDate = nextDate
524
- nextDate = cronTime.getNextDateFrom(currentDate)
525
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
526
- })
527
- // Do not think a similar test for secondly job is necessary, the minutely one already ensured no double hits in the overlap zone.
528
- it('should throw when dates that are not within 24 hours of DST jumps are checked for past DST jumps', () => {
529
- const cronTime = new CronTime('* * * * *')
530
- const tryFindPastDST = (isoTime: string) => () => {
531
- const maybeBadDate = DateTime.fromISO(isoTime, {
532
- zone: 'Asia/Amman',
533
- })
534
- expect(maybeBadDate.isValid).toBe(true)
535
- // @ts-expect-error testing private property
536
- cronTime._findPreviousDSTJump(maybeBadDate)
537
- }
538
-
539
- // This timezone jumps from 0:00 to 1:00 on March 30th, so the cutoff is March 31st 1:00:00
540
- expect(tryFindPastDST('2018-03-31T00:59:00')).not.toThrow()
541
- expect(tryFindPastDST('2018-03-31T01:00:00')).toThrow()
542
- })
543
- // The following few DST related tests do not need specific dates that are actually DST,
544
- // the functions they are calling assume the given parameters encapsulate a DST jump,
545
- // and use the raw hour and minute data to check it from there.
546
- it('should correctly scan time periods as if they are DST jumps, half hour jumps', () => {
547
- let endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
548
- zone: 'Europe/Amsterdam',
549
- })
550
- let startDate = endDate.minus({ minute: 30, second: 1 })
551
- const cronTime = new CronTime('5 16 * * *') // at 16:05:00.
552
- // @ts-expect-error testing private property
553
- let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
554
- expect(isJobInRange).toBe(false)
555
-
556
- endDate = endDate.plus({ minute: 30 }) // 16:30:00
557
- startDate = endDate.minus({ minute: 30, second: 1 }) // 15:59:59
558
- // @ts-expect-error testing private property
559
- isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
560
- expect(isJobInRange).toBe(true)
561
- })
562
- it('should not include seconds in the minute after the DST jump as part of the jump scan', () => {
563
- const endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
564
- zone: 'Europe/Amsterdam',
565
- })
566
- // 1 hour jump case
567
- let startDate = endDate.minus({ hour: 1, second: 1 })
568
- const cronTime = new CronTime('1 5 16 * * *') // at 16:00:01.
569
- // @ts-expect-error testing private property
570
- let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
571
- expect(isJobInRange).toBe(false)
572
- // 'quirky' jump case
573
- startDate = endDate.minus({ hour: 1, minute: 45, second: 1 })
574
- // @ts-expect-error testing private property
575
- isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
576
- expect(isJobInRange).toBe(false)
577
- })
578
- it('should correctly scan time periods as if they are DST jumps, full hour jumps', () => {
579
- let endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
580
- zone: 'Europe/Amsterdam',
581
- })
582
- let startDate = endDate.minus({ hour: 1, second: 1 })
583
- const cronTime = new CronTime('5 16 * * *') // at 16:05:00.
584
- // @ts-expect-error testing private property
585
- let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
586
- expect(isJobInRange).toBe(false)
587
-
588
- endDate = endDate.plus({ hour: 1 }) // 17:00:00
589
- startDate = endDate.minus({ hour: 1, second: 1 }) // 15:59:59
590
- // @ts-expect-error testing private property
591
- isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
592
- expect(isJobInRange).toBe(true)
593
- })
594
- // A 'quirky' DST jump is one that should not break the implementation, but does not exist in real life (yet)
595
- it('should correctly scan time periods as if they are DST jumps, quirky jumps (1)', () => {
596
- // Testing a jump that is less than an hour long, but wraps around an hour.
597
- let endDate = DateTime.fromISO('2023-01-01T16:15:00.000', {
598
- zone: 'Europe/Amsterdam',
599
- })
600
- let startDate = endDate.minus({ minute: 45, second: 1 }) // 15:29:59
601
- const cronTime = new CronTime('30 16 * * *') // at 16:30:00.
602
- // @ts-expect-error testing private property
603
- let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
604
- expect(isJobInRange).toBe(false)
605
-
606
- endDate = endDate.plus({ minute: 30 }) // 16:45:00
607
- startDate = endDate.minus({ minute: 50, second: 1 }) // 15:54:59
608
- // @ts-expect-error testing private property
609
- isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
610
- expect(isJobInRange).toBe(true)
611
- })
612
- it('should correctly scan time periods as if they are DST jumps, quirky jumps (2)', () => {
613
- // Testing a jump that is over an hour long.
614
- let endDate = DateTime.fromISO('2023-01-01T16:15:00.000', {
615
- zone: 'Europe/Amsterdam',
616
- })
617
- let startDate = endDate.minus({ hour: 3, minute: 45, second: 1 }) // 12:29:59
618
- const cronTime = new CronTime('30 16 * * *') // at 16:30:00.
619
- // @ts-expect-error testing private property
620
- let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
621
- expect(isJobInRange).toBe(false)
622
-
623
- endDate = endDate.plus({ minute: 30 }) // 16:45:00
624
- startDate = endDate.minus({ hour: 3, minute: 45, second: 1 }) // 12:59:59
625
- // @ts-expect-error testing private property
626
- isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
627
- expect(isJobInRange).toBe(true)
628
- })
629
- it('enforces the hour difference assumption for handling multi-hour DST jumps', () => {
630
- const cronTime = new CronTime('30 16 * * *')
631
- expect(() => {
632
- // @ts-expect-error testing private property
633
- cronTime._checkTimeInSkippedRangeMultiHour(15, 0, 15, 30)
634
- }).toThrow()
635
- })
636
- it('should generate the right N next days for * * * * *', () => {
637
- const cronTime = new CronTime('* * * * *')
638
- let currentDate = DateTime.local().set({ second: 0, millisecond: 0 })
639
- for (let i = 0; i < 100; i++) {
640
- const nextDate = cronTime.getNextDateFrom(currentDate)
641
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
642
- currentDate = nextDate
643
- }
644
- })
645
- it('should generate the right N next days for 0 0 9 * * *', () => {
646
- const cronTime = new CronTime('0 0 9 * * *')
647
- let currentDate = DateTime.local()
648
- .setZone('utc')
649
- .set({ hour: 9, minute: 0, second: 0, millisecond: 0 })
650
- for (let i = 0; i < 100; i++) {
651
- const nextDate = cronTime.getNextDateFrom(currentDate)
652
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
653
- 1000 * 60 * 60 * 24,
654
- )
655
- currentDate = nextDate
656
- }
657
- })
658
- it('should generate the right N next days for 0 0 * * * with a time zone', () => {
659
- const cronTime = new CronTime('0 * * * *')
660
- let currentDate = DateTime.fromISO('2018-11-02T23:00', {
661
- zone: 'America/Sao_Paulo',
662
- }).set({ second: 0, millisecond: 0 })
663
- for (let i = 0; i < 25; i++) {
664
- const nextDate = cronTime.getNextDateFrom(
665
- currentDate,
666
- 'America/Sao_Paulo',
667
- )
668
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
669
- 1000 * 60 * 60,
670
- )
671
- currentDate = nextDate
672
- }
673
- })
674
- it('should generate the right N next days for */3 * * * * with a time zone', () => {
675
- const cronTime = new CronTime('*/3 * * * *')
676
- let currentDate = DateTime.fromISO('2018-11-02T23:00', {
677
- zone: 'America/Sao_Paulo',
678
- }).set({ second: 0, millisecond: 0 })
679
- for (let i = 0; i < 25; i++) {
680
- const nextDate = cronTime.getNextDateFrom(
681
- currentDate,
682
- 'America/Sao_Paulo',
683
- )
684
- expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
685
- 1000 * 60 * 3,
686
- )
687
- currentDate = nextDate
688
- }
689
- })
690
- it('should test valid range of months (*/15 * * 7-12 *)', () => {
691
- const cronTime = new CronTime('*/15 * * 7-12 *')
692
- const previousDate1 = new Date(Date.UTC(2018, 3, 0, 0, 0))
693
- const nextDate1 = cronTime.getNextDateFrom(previousDate1, 'UTC')
694
- expect(nextDate1.toJSDate().toUTCString()).toEqual(
695
- new Date(Date.UTC(2018, 6, 1, 0, 0)).toUTCString(),
696
- )
697
- const previousDate2 = new Date(Date.UTC(2018, 8, 0, 0, 0))
698
- const nextDate2 = cronTime.getNextDateFrom(previousDate2, 'UTC')
699
- expect(nextDate2.toJSDate().toUTCString()).toEqual(
700
- new Date(Date.UTC(2018, 8, 0, 0, 15)).toUTCString(),
701
- )
702
- })
703
- it('should generate the right next day when cron is set to every 15 min in Feb', () => {
704
- const cronTime = new CronTime('*/15 * * FEB *')
705
- const previousDate = new Date(Date.UTC(2018, 3, 0, 0, 0))
706
- const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
707
- expect(nextDate.valueOf()).toEqual(
708
- new Date(Date.UTC(2019, 1, 1, 0, 0)).valueOf(),
709
- )
710
- })
711
- it('should generate the right next day when cron is set to both day of the month and day of the week (1)', () => {
712
- const cronTime = new CronTime('0 8 1 * 4')
713
- const previousDate = new Date(Date.UTC(2019, 3, 21, 0, 0))
714
- const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
715
- expect(nextDate.toMillis()).toEqual(
716
- new Date(Date.UTC(2019, 3, 25, 8, 0)).getTime(),
717
- )
718
- })
719
- it('should generate the right next day when cron is set to both day of the month and day of the week (2)', () => {
720
- const cronTime = new CronTime('0 8 1 * 4')
721
- const previousDate = new Date(Date.UTC(2019, 3, 26, 0, 0))
722
- const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
723
- expect(nextDate.toMillis()).toEqual(
724
- new Date(Date.UTC(2019, 4, 1, 8, 0)).getTime(),
725
- )
726
- })
727
- it('should generate the right next day when cron is set to both day of the month and day of the week (3)', () => {
728
- const cronTime = new CronTime('0 8 1 * 4')
729
- const previousDate = new Date(Date.UTC(2019, 7, 1, 7, 59))
730
- const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
731
- expect(nextDate.valueOf()).toEqual(
732
- new Date(Date.UTC(2019, 7, 1, 8, 0)).valueOf(),
733
- )
734
- })
735
-
736
- it('should accept 0 as a valid UTC offset', () => {
737
- const clock = sinon.useFakeTimers()
738
-
739
- const cronTime = new CronTime('0 11 * * *', null, 0)
740
- const expected = DateTime.local().plus({ hours: 11 }).toSeconds()
741
- const actual = cronTime.sendAt().toSeconds()
742
-
743
- expect(actual).toEqual(expected)
744
-
745
- clock.restore()
746
- })
747
-
748
- it('should accept -120 as a valid UTC offset', () => {
749
- const clock = sinon.useFakeTimers()
750
-
751
- const cronTime = new CronTime('0 11 * * *', null, -120)
752
- const expected = DateTime.local().plus({ hours: 13 }).toSeconds()
753
- const actual = cronTime.sendAt().toSeconds()
754
-
755
- expect(actual).toEqual(expected)
756
-
757
- clock.restore()
758
- })
759
-
760
- it('should detect real date in the past', () => {
761
- const clock = sinon.useFakeTimers()
762
-
763
- const d = new Date()
764
- clock.tick(1000)
765
- const time = new CronTime(d)
766
- expect(() => {
767
- time.sendAt()
768
- }).toThrow()
769
- clock.restore()
770
- })
771
-
772
- it('should throw when providing both exclusive parameters timeZone and utcOffset', () => {
773
- expect(() => {
774
- // @ts-expect-error testing runtime exception
775
- new CronTime('* * * * *', 'Asia/Amman', 120)
776
- }).toThrow()
777
- })
778
- })
1
+ // /* eslint-disable no-new */
2
+ // import { DateTime } from 'luxon'
3
+ //
4
+ // // @ts-expect-error - somehow types are missing even though they are installed
5
+ // import sinon from 'sinon'
6
+ // import { CronTime } from '../src'
7
+ //
8
+ // describe('crontime', () => {
9
+ // afterEach(() => expect.hasAssertions())
10
+ //
11
+ // it('should test stars (* * * * * *)', () => {
12
+ // expect(() => {
13
+ // new CronTime('* * * * * *')
14
+ // }).not.toThrow()
15
+ // })
16
+ //
17
+ // it('should test digit (0 * * * * *)', () => {
18
+ // expect(() => {
19
+ // new CronTime('0 * * * * *')
20
+ // }).not.toThrow()
21
+ // })
22
+ //
23
+ // it('should test multi digits (08 * * * * *)', () => {
24
+ // expect(() => {
25
+ // new CronTime('08 * * * * *')
26
+ // }).not.toThrow()
27
+ // })
28
+ //
29
+ // it('should test all digits (08 8 8 8 8 5)', () => {
30
+ // expect(() => {
31
+ // new CronTime('08 * * * * *')
32
+ // }).not.toThrow()
33
+ // })
34
+ //
35
+ // it('should test too many digits (08 8 8 8 8 5)', () => {
36
+ // expect(() => {
37
+ // new CronTime('08 * * * * *')
38
+ // }).not.toThrow()
39
+ // })
40
+ //
41
+ // it('should test standard cron format (* * * * *)', () => {
42
+ // expect(() => {
43
+ // new CronTime('* * * * *')
44
+ // }).not.toThrow()
45
+ // })
46
+ //
47
+ // it('should test standard cron format (8 8 8 8 5)', () => {
48
+ // const standard = new CronTime('8 8 8 8 5')
49
+ // const extended = new CronTime('0 8 8 8 8 5')
50
+ //
51
+ // // @ts-expect-error deleting for comparaison purposes
52
+ // delete standard.source
53
+ // // @ts-expect-error deleting for comparaison purposes
54
+ // delete extended.source
55
+ //
56
+ // expect(extended).toEqual(standard)
57
+ // })
58
+ //
59
+ // it('should test hyphen (0-10 * * * * *)', () => {
60
+ // expect(() => {
61
+ // new CronTime('0-10 * * * * *')
62
+ // }).not.toThrow()
63
+ // })
64
+ //
65
+ // it('should test multi hyphens (0-10 0-10 * * * *)', () => {
66
+ // expect(() => {
67
+ // new CronTime('0-10 0-10 * * * *')
68
+ // }).not.toThrow()
69
+ // })
70
+ //
71
+ // it('should test all hyphens (0-10 0-10 1-10 1-10 1-7 0-1)', () => {
72
+ // expect(() => {
73
+ // new CronTime('0-10 0-10 1-10 1-10 1-7 0-1')
74
+ // }).not.toThrow()
75
+ // })
76
+ //
77
+ // it('should accept all valid ranges (0-59 0-59 0-23 1-31 1-12 0-7)', () => {
78
+ // expect(() => {
79
+ // new CronTime('0-59 0-59 0-23 1-31 1-12 0-7')
80
+ // }).not.toThrow()
81
+ // })
82
+ //
83
+ // it('should test comma (0,10 * * * * *)', () => {
84
+ // expect(() => {
85
+ // new CronTime('0,10 * * * * *')
86
+ // }).not.toThrow()
87
+ // })
88
+ //
89
+ // it('should test multi commas (0,10 0,10 * * * *)', () => {
90
+ // expect(() => {
91
+ // new CronTime('0,10 0,10 * * * *')
92
+ // }).not.toThrow()
93
+ // })
94
+ //
95
+ // it('should test all commas (0,10 0,10 1,10 1,10 1,7 0,1)', () => {
96
+ // expect(() => {
97
+ // new CronTime('0,10 0,10 1,10 1,10 1,7 0,1')
98
+ // }).not.toThrow()
99
+ // })
100
+ //
101
+ // it('should test alias (* * * * jan *)', () => {
102
+ // expect(() => {
103
+ // new CronTime('* * * * jan *')
104
+ // }).not.toThrow()
105
+ // })
106
+ //
107
+ // it('should test multi aliases (* * * * jan,feb *)', () => {
108
+ // expect(() => {
109
+ // new CronTime('* * * * jan,feb *')
110
+ // }).not.toThrow()
111
+ // })
112
+ //
113
+ // it('should test all aliases (* * * * jan,feb mon,tue)', () => {
114
+ // expect(() => {
115
+ // new CronTime('* * * * jan,feb mon,tue')
116
+ // }).not.toThrow()
117
+ // })
118
+ //
119
+ // it('should test unknown alias (* * * * jar *)', () => {
120
+ // expect(() => {
121
+ // new CronTime('* * * * jar *')
122
+ // }).toThrow()
123
+ // })
124
+ //
125
+ // it('should test unknown alias - short (* * * * j *)', () => {
126
+ // expect(() => {
127
+ // new CronTime('* * * * j *')
128
+ // }).toThrow()
129
+ // })
130
+ //
131
+ // it('should be case-insensitive for aliases (* * * * JAN,FEB MON,TUE)', () => {
132
+ // expect(() => {
133
+ // new CronTime('* * * * JAN,FEB MON,TUE', null, null)
134
+ // }).not.toThrow()
135
+ // })
136
+ //
137
+ // it('should test too few fields', () => {
138
+ // expect(() => {
139
+ // new CronTime('* * * *', null, null)
140
+ // }).toThrow()
141
+ // })
142
+ //
143
+ // it('should test too many fields', () => {
144
+ // expect(() => {
145
+ // new CronTime('* * * * * * *', null, null)
146
+ // }).toThrow()
147
+ // })
148
+ //
149
+ // it('should return the same object with 0 & 7 as Sunday (except "source" prop)', () => {
150
+ // const sunday0 = new CronTime('* * * * 0', null, null)
151
+ // const sunday7 = new CronTime('* * * * 7', null, null)
152
+ //
153
+ // // @ts-expect-error deleting for comparaison purposes
154
+ // delete sunday0.source
155
+ // // @ts-expect-error deleting for comparaison purposes
156
+ // delete sunday7.source
157
+ //
158
+ // expect(sunday7).toEqual(sunday0)
159
+ // })
160
+ //
161
+ // describe('should test out of range values', () => {
162
+ // it('should test out of range minute', () => {
163
+ // expect(() => {
164
+ // new CronTime('-1 * * * *', null, null)
165
+ // }).toThrow()
166
+ // expect(() => {
167
+ // new CronTime('60 * * * *', null, null)
168
+ // }).toThrow()
169
+ // })
170
+ //
171
+ // it('should test out of range hour', () => {
172
+ // expect(() => {
173
+ // new CronTime('* -1 * * *', null, null)
174
+ // }).toThrow()
175
+ // expect(() => {
176
+ // new CronTime('* 24 * * *', null, null)
177
+ // }).toThrow()
178
+ // })
179
+ //
180
+ // it('should test out of range day-of-month', () => {
181
+ // expect(() => {
182
+ // new CronTime('* * 0 * *', null, null)
183
+ // }).toThrow()
184
+ // expect(() => {
185
+ // new CronTime('* * 32 * *', null, null)
186
+ // }).toThrow()
187
+ // })
188
+ //
189
+ // it('should test out of range month', () => {
190
+ // expect(() => {
191
+ // new CronTime('* * * 0 *', null, null)
192
+ // }).toThrow()
193
+ // expect(() => {
194
+ // new CronTime('* * * 13 *', null, null)
195
+ // }).toThrow()
196
+ // })
197
+ //
198
+ // it('should test out of range day-of-week', () => {
199
+ // expect(() => {
200
+ // new CronTime('* * * * -1', null, null)
201
+ // }).toThrow()
202
+ // expect(() => {
203
+ // new CronTime('* * * * 8', null, null)
204
+ // }).toThrow()
205
+ // })
206
+ // })
207
+ //
208
+ // it('should test invalid wildcard expression', () => {
209
+ // expect(() => {
210
+ // new CronTime('* * * * 0*')
211
+ // }).toThrow()
212
+ // })
213
+ //
214
+ // it('should test invalid step', () => {
215
+ // expect(() => {
216
+ // new CronTime('* * * 1/ *')
217
+ // }).toThrow()
218
+ //
219
+ // expect(() => {
220
+ // new CronTime('* * * 1/0 *')
221
+ // }).toThrow()
222
+ //
223
+ // expect(() => {
224
+ // new CronTime('* * * 1/00 *')
225
+ // }).toThrow()
226
+ // })
227
+ //
228
+ // it('should test invalid range', () => {
229
+ // expect(() => {
230
+ // new CronTime('* 2-1 * * *')
231
+ // }).toThrow()
232
+ //
233
+ // expect(() => {
234
+ // new CronTime('* 2-0 * * *')
235
+ // }).toThrow()
236
+ //
237
+ // expect(() => {
238
+ // new CronTime('* 2- * * *')
239
+ // }).toThrow()
240
+ // })
241
+ //
242
+ // it('should test Date', () => {
243
+ // const d = new Date()
244
+ // const ct = new CronTime(d)
245
+ // expect(ct.source).toBeInstanceOf(DateTime)
246
+ // expect((ct.source as DateTime).toMillis()).toEqual(d.getTime())
247
+ // })
248
+ //
249
+ // it('should test day roll-over', () => {
250
+ // const numHours = 24
251
+ // const ct = new CronTime('0 0 17 * * *')
252
+ //
253
+ // for (let hr = 0; hr < numHours; hr++) {
254
+ // const start = new Date(2012, 3, 16, hr, 30, 30)
255
+ // const next = ct.getNextDateFrom(start)
256
+ // expect(next.toMillis() - start.getTime()).toBeLessThan(
257
+ // 24 * 60 * 60 * 1000,
258
+ // )
259
+ // expect(next.toMillis()).toBeGreaterThan(start.getTime())
260
+ // }
261
+ // })
262
+ //
263
+ // it('should test illegal repetition syntax', () => {
264
+ // expect(() => {
265
+ // new CronTime('* * /4 * * *')
266
+ // }).toThrow()
267
+ // })
268
+ //
269
+ // it('should test next date', () => {
270
+ // const ct = new CronTime('0 0 */4 * * *')
271
+ //
272
+ // const nextDate = new Date()
273
+ // nextDate.setHours(23)
274
+ // const nextdt = ct.getNextDateFrom(nextDate)
275
+ //
276
+ // expect(nextdt.toMillis()).toBeGreaterThan(nextDate.getTime())
277
+ // expect(nextdt.hour % 4).toBe(0)
278
+ // })
279
+ //
280
+ // it('should throw an exception because next date is invalid', () => {
281
+ // const ct = new CronTime('0 0 * * * *')
282
+ // const nextDate = new Date('My invalid date string')
283
+ //
284
+ // expect(() => {
285
+ // ct.getNextDateFrom(nextDate)
286
+ // }).toThrow('ERROR: You specified an invalid date.')
287
+ // })
288
+ //
289
+ // it('should test next real date', () => {
290
+ // const initialDate = new Date()
291
+ // initialDate.setDate(initialDate.getDate() + 1) // In other case date will be in the past
292
+ // const ct = new CronTime(initialDate)
293
+ //
294
+ // const nextDate = new Date()
295
+ // nextDate.setMonth(nextDate.getMonth() + 1)
296
+ // expect(ct.source).toBeInstanceOf(DateTime)
297
+ // expect(nextDate.getTime()).toBeGreaterThan(
298
+ // (ct.source as DateTime).toMillis(),
299
+ // )
300
+ // const nextDt = ct.sendAt()
301
+ // // there shouldn't be a "next date" when using a real date.
302
+ // // execution happens once
303
+ // // so the return should be the date passed in unless explicitly reset
304
+ // expect(nextDt.toMillis() < nextDate.getTime()).toBeTruthy()
305
+ // expect(nextDt.toMillis()).toEqual(initialDate.getTime())
306
+ // })
307
+ //
308
+ // describe('presets', () => {
309
+ // it('should parse @secondly', () => {
310
+ // const cronTime = new CronTime('@secondly')
311
+ // expect(cronTime.toString()).toBe('* * * * * *')
312
+ // })
313
+ //
314
+ // it('should parse @minutely', () => {
315
+ // const cronTime = new CronTime('@minutely')
316
+ // expect(cronTime.toString()).toBe('0 * * * * *')
317
+ // })
318
+ //
319
+ // it('should parse @hourly', () => {
320
+ // const cronTime = new CronTime('@hourly')
321
+ // expect(cronTime.toString()).toBe('0 0 * * * *')
322
+ // })
323
+ //
324
+ // it('should parse @daily', () => {
325
+ // const cronTime = new CronTime('@daily')
326
+ // expect(cronTime.toString()).toBe('0 0 0 * * *')
327
+ // })
328
+ //
329
+ // it('should parse @weekly', () => {
330
+ // const cronTime = new CronTime('@weekly')
331
+ // expect(cronTime.toString()).toBe('0 0 0 * * 0')
332
+ // })
333
+ //
334
+ // it('should parse @weekdays', () => {
335
+ // const cronTime = new CronTime('@weekdays')
336
+ // expect(cronTime.toString()).toBe('0 0 0 * * 1,2,3,4,5')
337
+ // })
338
+ //
339
+ // it('should parse @weekends', () => {
340
+ // const cronTime = new CronTime('@weekends')
341
+ // expect(cronTime.toString()).toBe('0 0 0 * * 0,6')
342
+ // })
343
+ //
344
+ // it('should parse @monthly', () => {
345
+ // const cronTime = new CronTime('@monthly')
346
+ // expect(cronTime.toString()).toBe('0 0 0 1 * *')
347
+ // })
348
+ //
349
+ // it('should parse @yearly', () => {
350
+ // const cronTime = new CronTime('@yearly')
351
+ // expect(cronTime.toString()).toBe('0 0 0 1 1 *')
352
+ // })
353
+ // })
354
+ //
355
+ // describe('should throw an exception because `L` not supported', () => {
356
+ // it('(* * * L * *)', () => {
357
+ // expect(() => {
358
+ // new CronTime('* * * L * *')
359
+ // }).toThrow()
360
+ // })
361
+ //
362
+ // it('(* * * * * L)', () => {
363
+ // expect(() => {
364
+ // new CronTime('* * * * * L')
365
+ // }).toThrow()
366
+ // })
367
+ // })
368
+ //
369
+ // it('should strip off millisecond', () => {
370
+ // const cronTime = new CronTime('0 */10 * * * *')
371
+ // const x = cronTime.getNextDateFrom(new Date('2018-08-10T02:20:00.999Z'))
372
+ // expect(x.toMillis()).toEqual(
373
+ // new Date('2018-08-10T02:30:00.000Z').getTime(),
374
+ // )
375
+ // })
376
+ //
377
+ // it('should strip off millisecond (2)', () => {
378
+ // const cronTime = new CronTime('0 */10 * * * *')
379
+ // const x = cronTime.getNextDateFrom(new Date('2018-08-10T02:19:59.999Z'))
380
+ // expect(x.toMillis()).toEqual(
381
+ // new Date('2018-08-10T02:20:00.000Z').getTime(),
382
+ // )
383
+ // })
384
+ //
385
+ // it('should expose getNextDateFrom as a public function', () => {
386
+ // const cronTime = new CronTime('0 */10 * * * *')
387
+ // cronTime.getNextDateFrom = jest.fn()
388
+ //
389
+ // const testDate = new Date('2018-08-10T02:19:59.999Z')
390
+ // const testTimezone = 'Asia/Amman'
391
+ // cronTime.getNextDateFrom(testDate, testTimezone)
392
+ //
393
+ // expect(cronTime.getNextDateFrom).toHaveBeenCalledWith(
394
+ // testDate,
395
+ // testTimezone,
396
+ // )
397
+ // })
398
+ //
399
+ // it('should generate the right next days when cron is set to every minute', () => {
400
+ // const cronTime = new CronTime('* * * * *')
401
+ // const min = 60000
402
+ // let previousDate = DateTime.fromMillis(Date.UTC(2018, 5, 3, 0, 0))
403
+ // for (let i = 0; i < 25; i++) {
404
+ // const nextDate = cronTime.getNextDateFrom(previousDate)
405
+ // expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min)
406
+ // previousDate = nextDate
407
+ // }
408
+ // })
409
+ //
410
+ // it('should generate the right next days when cron is set to every 15 min', () => {
411
+ // const cronTime = new CronTime('*/15 * * * *')
412
+ // const min = 60000 * 15
413
+ // let previousDate = DateTime.fromMillis(Date.UTC(2016, 6, 3, 0, 0))
414
+ // for (let i = 0; i < 25; i++) {
415
+ // const nextDate = cronTime.getNextDateFrom(previousDate)
416
+ // expect(nextDate.valueOf()).toEqual(previousDate.valueOf() + min)
417
+ // previousDate = nextDate
418
+ // }
419
+ // })
420
+ // it('should work around time zone changes that shifts time back (1)', () => {
421
+ // const d = new Date('10-7-2018')
422
+ // // America/Sao_Paulo has a time zone change around NOV 3 2018.
423
+ // const cronTime = new CronTime('0 0 9 4 * *')
424
+ // const nextDate = cronTime.getNextDateFrom(d, 'America/Sao_Paulo')
425
+ // expect(nextDate.valueOf()).toEqual(
426
+ // DateTime.fromISO('2018-11-04T09:00:00.000-02:00').valueOf(),
427
+ // )
428
+ // })
429
+ // it('should work around time zone changes that shifts time back (2)', () => {
430
+ // // Asia/Amman DST ends in 26 - OCT-2018 (-1 to hours)
431
+ // const currentDate = DateTime.fromISO('2018-10-25T23:00', {
432
+ // zone: 'Asia/Amman',
433
+ // })
434
+ // const cronTime = new CronTime('0 0 * * *')
435
+ // const nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
436
+ // const expectedDate = DateTime.fromISO('2018-10-26T00:00+03:00', {
437
+ // zone: 'Asia/Amman',
438
+ // })
439
+ // expect(nextDate.toMillis() - expectedDate.toMillis()).toBe(0)
440
+ // })
441
+ // it('should work around time zone changes that shifts time forward', () => {
442
+ // // Asia/Amman DST starts in 30-March-2018 (+1 to hours)
443
+ // let currentDate = DateTime.fromISO('2018-03-29T23:00', {
444
+ // zone: 'Asia/Amman',
445
+ // })
446
+ // const cronTime = new CronTime('* * * * *')
447
+ // for (let i = 0; i < 100; i++) {
448
+ // const nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
449
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
450
+ // currentDate = nextDate
451
+ // }
452
+ // })
453
+ // it('should schedule jobs inside time zone changes that shifts time forward to the end of the shift, for weekly jobs', () => {
454
+ // let currentDate = DateTime.fromISO('2018-03-29T23:15', {
455
+ // zone: 'Asia/Amman',
456
+ // })
457
+ // const cronTime = new CronTime('30 0 * * 5') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
458
+ // let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
459
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
460
+ // 1000 * 60 * 45,
461
+ // ) // 45 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
462
+ // // the next one should just be at 0:30 again. i.e. a week minus 30 minutes.
463
+ // currentDate = nextDate
464
+ // nextDate = cronTime.getNextDateFrom(currentDate)
465
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
466
+ // 3600000 * 24 * 7 - 60000 * 30,
467
+ // )
468
+ // // the next one is again at 0:30, but now we're 'back to normal' with weekly offsets.
469
+ // currentDate = nextDate
470
+ // nextDate = cronTime.getNextDateFrom(currentDate)
471
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
472
+ // 1000 * 3600 * 24 * 7,
473
+ // )
474
+ // })
475
+ // it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for daily jobs', () => {
476
+ // let currentDate = DateTime.fromISO('2018-03-29T23:45', {
477
+ // zone: 'Asia/Amman',
478
+ // })
479
+ // const cronTime = new CronTime('30 0 * * *') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
480
+ // let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
481
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
482
+ // 1000 * 60 * 15,
483
+ // ) // 15 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
484
+ // // the next one is tomorrow at 0:30, so 23h30m.
485
+ // currentDate = nextDate
486
+ // nextDate = cronTime.getNextDateFrom(currentDate)
487
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
488
+ // 1000 * 3600 * 24 - 1000 * 60 * 30,
489
+ // )
490
+ // // back to normal.
491
+ // currentDate = nextDate
492
+ // nextDate = cronTime.getNextDateFrom(currentDate)
493
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
494
+ // 1000 * 3600 * 24,
495
+ // )
496
+ // })
497
+ // it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for hourly jobs', () => {
498
+ // let currentDate = DateTime.fromISO('2018-03-29T23:45', {
499
+ // zone: 'Asia/Amman',
500
+ // })
501
+ // const cronTime = new CronTime('30 * * * *') // the next 0:30 is March 30th, but it will jump from 0:00 to 1:00.
502
+ // let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
503
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
504
+ // 1000 * 60 * 15,
505
+ // ) // 15 minutes is 30T00:00, which jumps to 1:00 which is past the trigger of 0:30.
506
+ // // the next one is at 1:30, so 30m.
507
+ // currentDate = nextDate
508
+ // nextDate = cronTime.getNextDateFrom(currentDate)
509
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
510
+ // 1000 * 60 * 30,
511
+ // )
512
+ // // back to normal.
513
+ // currentDate = nextDate
514
+ // nextDate = cronTime.getNextDateFrom(currentDate)
515
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 3600)
516
+ // })
517
+ // it('should schedule jobs inside time zone changes that shifts the time forward to the end of the shift, for minutely jobs', () => {
518
+ // let currentDate = DateTime.fromISO('2018-03-29T23:59', {
519
+ // zone: 'Asia/Amman',
520
+ // })
521
+ // const cronTime = new CronTime('* * * * *') // the next minute is 0:00 is March 30th, but it will jump from 0:00 to 1:00.
522
+ // let nextDate = cronTime.getNextDateFrom(currentDate, 'Asia/Amman')
523
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
524
+ // // the next one is at 1:01:00, this should still be 60 seconds in the future.
525
+ // currentDate = nextDate
526
+ // nextDate = cronTime.getNextDateFrom(currentDate)
527
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
528
+ // })
529
+ // // Do not think a similar test for secondly job is necessary, the minutely one already ensured no double hits in the overlap zone.
530
+ // it('should throw when dates that are not within 24 hours of DST jumps are checked for past DST jumps', () => {
531
+ // const cronTime = new CronTime('* * * * *')
532
+ // const tryFindPastDST = (isoTime: string) => () => {
533
+ // const maybeBadDate = DateTime.fromISO(isoTime, {
534
+ // zone: 'Asia/Amman',
535
+ // })
536
+ // expect(maybeBadDate.isValid).toBe(true)
537
+ // // @ts-expect-error testing private property
538
+ // cronTime._findPreviousDSTJump(maybeBadDate)
539
+ // }
540
+ //
541
+ // // This timezone jumps from 0:00 to 1:00 on March 30th, so the cutoff is March 31st 1:00:00
542
+ // expect(tryFindPastDST('2018-03-31T00:59:00')).not.toThrow()
543
+ // expect(tryFindPastDST('2018-03-31T01:00:00')).toThrow()
544
+ // })
545
+ // // The following few DST related tests do not need specific dates that are actually DST,
546
+ // // the functions they are calling assume the given parameters encapsulate a DST jump,
547
+ // // and use the raw hour and minute data to check it from there.
548
+ // it('should correctly scan time periods as if they are DST jumps, half hour jumps', () => {
549
+ // let endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
550
+ // zone: 'Europe/Amsterdam',
551
+ // })
552
+ // let startDate = endDate.minus({ minute: 30, second: 1 })
553
+ // const cronTime = new CronTime('5 16 * * *') // at 16:05:00.
554
+ // // @ts-expect-error testing private property
555
+ // let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
556
+ // expect(isJobInRange).toBe(false)
557
+ //
558
+ // endDate = endDate.plus({ minute: 30 }) // 16:30:00
559
+ // startDate = endDate.minus({ minute: 30, second: 1 }) // 15:59:59
560
+ // // @ts-expect-error testing private property
561
+ // isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
562
+ // expect(isJobInRange).toBe(true)
563
+ // })
564
+ // it('should not include seconds in the minute after the DST jump as part of the jump scan', () => {
565
+ // const endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
566
+ // zone: 'Europe/Amsterdam',
567
+ // })
568
+ // // 1 hour jump case
569
+ // let startDate = endDate.minus({ hour: 1, second: 1 })
570
+ // const cronTime = new CronTime('1 5 16 * * *') // at 16:00:01.
571
+ // // @ts-expect-error testing private property
572
+ // let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
573
+ // expect(isJobInRange).toBe(false)
574
+ // // 'quirky' jump case
575
+ // startDate = endDate.minus({ hour: 1, minute: 45, second: 1 })
576
+ // // @ts-expect-error testing private property
577
+ // isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
578
+ // expect(isJobInRange).toBe(false)
579
+ // })
580
+ // it('should correctly scan time periods as if they are DST jumps, full hour jumps', () => {
581
+ // let endDate = DateTime.fromISO('2023-01-01T16:00:00.000', {
582
+ // zone: 'Europe/Amsterdam',
583
+ // })
584
+ // let startDate = endDate.minus({ hour: 1, second: 1 })
585
+ // const cronTime = new CronTime('5 16 * * *') // at 16:05:00.
586
+ // // @ts-expect-error testing private property
587
+ // let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
588
+ // expect(isJobInRange).toBe(false)
589
+ //
590
+ // endDate = endDate.plus({ hour: 1 }) // 17:00:00
591
+ // startDate = endDate.minus({ hour: 1, second: 1 }) // 15:59:59
592
+ // // @ts-expect-error testing private property
593
+ // isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
594
+ // expect(isJobInRange).toBe(true)
595
+ // })
596
+ // // A 'quirky' DST jump is one that should not break the implementation, but does not exist in real life (yet)
597
+ // it('should correctly scan time periods as if they are DST jumps, quirky jumps (1)', () => {
598
+ // // Testing a jump that is less than an hour long, but wraps around an hour.
599
+ // let endDate = DateTime.fromISO('2023-01-01T16:15:00.000', {
600
+ // zone: 'Europe/Amsterdam',
601
+ // })
602
+ // let startDate = endDate.minus({ minute: 45, second: 1 }) // 15:29:59
603
+ // const cronTime = new CronTime('30 16 * * *') // at 16:30:00.
604
+ // // @ts-expect-error testing private property
605
+ // let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
606
+ // expect(isJobInRange).toBe(false)
607
+ //
608
+ // endDate = endDate.plus({ minute: 30 }) // 16:45:00
609
+ // startDate = endDate.minus({ minute: 50, second: 1 }) // 15:54:59
610
+ // // @ts-expect-error testing private property
611
+ // isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
612
+ // expect(isJobInRange).toBe(true)
613
+ // })
614
+ // it('should correctly scan time periods as if they are DST jumps, quirky jumps (2)', () => {
615
+ // // Testing a jump that is over an hour long.
616
+ // let endDate = DateTime.fromISO('2023-01-01T16:15:00.000', {
617
+ // zone: 'Europe/Amsterdam',
618
+ // })
619
+ // let startDate = endDate.minus({ hour: 3, minute: 45, second: 1 }) // 12:29:59
620
+ // const cronTime = new CronTime('30 16 * * *') // at 16:30:00.
621
+ // // @ts-expect-error testing private property
622
+ // let isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
623
+ // expect(isJobInRange).toBe(false)
624
+ //
625
+ // endDate = endDate.plus({ minute: 30 }) // 16:45:00
626
+ // startDate = endDate.minus({ hour: 3, minute: 45, second: 1 }) // 12:59:59
627
+ // // @ts-expect-error testing private property
628
+ // isJobInRange = cronTime._checkTimeInSkippedRange(startDate, endDate)
629
+ // expect(isJobInRange).toBe(true)
630
+ // })
631
+ // it('enforces the hour difference assumption for handling multi-hour DST jumps', () => {
632
+ // const cronTime = new CronTime('30 16 * * *')
633
+ // expect(() => {
634
+ // // @ts-expect-error testing private property
635
+ // cronTime._checkTimeInSkippedRangeMultiHour(15, 0, 15, 30)
636
+ // }).toThrow()
637
+ // })
638
+ // it('should generate the right N next days for * * * * *', () => {
639
+ // const cronTime = new CronTime('* * * * *')
640
+ // let currentDate = DateTime.local().set({ second: 0, millisecond: 0 })
641
+ // for (let i = 0; i < 100; i++) {
642
+ // const nextDate = cronTime.getNextDateFrom(currentDate)
643
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(1000 * 60)
644
+ // currentDate = nextDate
645
+ // }
646
+ // })
647
+ // it('should generate the right N next days for 0 0 9 * * *', () => {
648
+ // const cronTime = new CronTime('0 0 9 * * *')
649
+ // let currentDate = DateTime.local()
650
+ // .setZone('utc')
651
+ // .set({ hour: 9, minute: 0, second: 0, millisecond: 0 })
652
+ // for (let i = 0; i < 100; i++) {
653
+ // const nextDate = cronTime.getNextDateFrom(currentDate)
654
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
655
+ // 1000 * 60 * 60 * 24,
656
+ // )
657
+ // currentDate = nextDate
658
+ // }
659
+ // })
660
+ // it('should generate the right N next days for 0 0 * * * with a time zone', () => {
661
+ // const cronTime = new CronTime('0 * * * *')
662
+ // let currentDate = DateTime.fromISO('2018-11-02T23:00', {
663
+ // zone: 'America/Sao_Paulo',
664
+ // }).set({ second: 0, millisecond: 0 })
665
+ // for (let i = 0; i < 25; i++) {
666
+ // const nextDate = cronTime.getNextDateFrom(
667
+ // currentDate,
668
+ // 'America/Sao_Paulo',
669
+ // )
670
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
671
+ // 1000 * 60 * 60,
672
+ // )
673
+ // currentDate = nextDate
674
+ // }
675
+ // })
676
+ // it('should generate the right N next days for */3 * * * * with a time zone', () => {
677
+ // const cronTime = new CronTime('*/3 * * * *')
678
+ // let currentDate = DateTime.fromISO('2018-11-02T23:00', {
679
+ // zone: 'America/Sao_Paulo',
680
+ // }).set({ second: 0, millisecond: 0 })
681
+ // for (let i = 0; i < 25; i++) {
682
+ // const nextDate = cronTime.getNextDateFrom(
683
+ // currentDate,
684
+ // 'America/Sao_Paulo',
685
+ // )
686
+ // expect(nextDate.toMillis() - currentDate.toMillis()).toEqual(
687
+ // 1000 * 60 * 3,
688
+ // )
689
+ // currentDate = nextDate
690
+ // }
691
+ // })
692
+ // it('should test valid range of months (*/15 * * 7-12 *)', () => {
693
+ // const cronTime = new CronTime('*/15 * * 7-12 *')
694
+ // const previousDate1 = new Date(Date.UTC(2018, 3, 0, 0, 0))
695
+ // const nextDate1 = cronTime.getNextDateFrom(previousDate1, 'UTC')
696
+ // expect(nextDate1.toJSDate().toUTCString()).toEqual(
697
+ // new Date(Date.UTC(2018, 6, 1, 0, 0)).toUTCString(),
698
+ // )
699
+ // const previousDate2 = new Date(Date.UTC(2018, 8, 0, 0, 0))
700
+ // const nextDate2 = cronTime.getNextDateFrom(previousDate2, 'UTC')
701
+ // expect(nextDate2.toJSDate().toUTCString()).toEqual(
702
+ // new Date(Date.UTC(2018, 8, 0, 0, 15)).toUTCString(),
703
+ // )
704
+ // })
705
+ // it('should generate the right next day when cron is set to every 15 min in Feb', () => {
706
+ // const cronTime = new CronTime('*/15 * * FEB *')
707
+ // const previousDate = new Date(Date.UTC(2018, 3, 0, 0, 0))
708
+ // const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
709
+ // expect(nextDate.valueOf()).toEqual(
710
+ // new Date(Date.UTC(2019, 1, 1, 0, 0)).valueOf(),
711
+ // )
712
+ // })
713
+ // it('should generate the right next day when cron is set to both day of the month and day of the week (1)', () => {
714
+ // const cronTime = new CronTime('0 8 1 * 4')
715
+ // const previousDate = new Date(Date.UTC(2019, 3, 21, 0, 0))
716
+ // const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
717
+ // expect(nextDate.toMillis()).toEqual(
718
+ // new Date(Date.UTC(2019, 3, 25, 8, 0)).getTime(),
719
+ // )
720
+ // })
721
+ // it('should generate the right next day when cron is set to both day of the month and day of the week (2)', () => {
722
+ // const cronTime = new CronTime('0 8 1 * 4')
723
+ // const previousDate = new Date(Date.UTC(2019, 3, 26, 0, 0))
724
+ // const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
725
+ // expect(nextDate.toMillis()).toEqual(
726
+ // new Date(Date.UTC(2019, 4, 1, 8, 0)).getTime(),
727
+ // )
728
+ // })
729
+ // it('should generate the right next day when cron is set to both day of the month and day of the week (3)', () => {
730
+ // const cronTime = new CronTime('0 8 1 * 4')
731
+ // const previousDate = new Date(Date.UTC(2019, 7, 1, 7, 59))
732
+ // const nextDate = cronTime.getNextDateFrom(previousDate, 'UTC')
733
+ // expect(nextDate.valueOf()).toEqual(
734
+ // new Date(Date.UTC(2019, 7, 1, 8, 0)).valueOf(),
735
+ // )
736
+ // })
737
+ //
738
+ // it('should accept 0 as a valid UTC offset', () => {
739
+ // const clock = sinon.useFakeTimers()
740
+ //
741
+ // const cronTime = new CronTime('0 11 * * *', null, 0)
742
+ // const expected = DateTime.local().plus({ hours: 11 }).toSeconds()
743
+ // const actual = cronTime.sendAt().toSeconds()
744
+ //
745
+ // expect(actual).toEqual(expected)
746
+ //
747
+ // clock.restore()
748
+ // })
749
+ //
750
+ // it('should accept -120 as a valid UTC offset', () => {
751
+ // const clock = sinon.useFakeTimers()
752
+ //
753
+ // const cronTime = new CronTime('0 11 * * *', null, -120)
754
+ // const expected = DateTime.local().plus({ hours: 13 }).toSeconds()
755
+ // const actual = cronTime.sendAt().toSeconds()
756
+ //
757
+ // expect(actual).toEqual(expected)
758
+ //
759
+ // clock.restore()
760
+ // })
761
+ //
762
+ // it('should detect real date in the past', () => {
763
+ // const clock = sinon.useFakeTimers()
764
+ //
765
+ // const d = new Date()
766
+ // clock.tick(1000)
767
+ // const time = new CronTime(d)
768
+ // expect(() => {
769
+ // time.sendAt()
770
+ // }).toThrow()
771
+ // clock.restore()
772
+ // })
773
+ //
774
+ // it('should throw when providing both exclusive parameters timeZone and utcOffset', () => {
775
+ // expect(() => {
776
+ // // @ts-expect-error testing runtime exception
777
+ // new CronTime('* * * * *', 'Asia/Amman', 120)
778
+ // }).toThrow()
779
+ // })
780
+ // })