Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4618d4d

Browse filesBrowse files
committed
feat(quartz): Steps starting from x #76
1 parent c1f80c1 commit 4618d4d
Copy full SHA for 4618d4d

File tree

Expand file treeCollapse file tree

6 files changed

+52
-20
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+52
-20
lines changed
Open diff view settings
Collapse file

‎core/src/__tests__/cron.spec.ts‎

Copy file name to clipboardExpand all lines: core/src/__tests__/cron.spec.ts
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { arrayToSegment, cronToSegment } from '@/cron'
2-
import { FieldWrapper } from '@/types'
2+
import { FieldWrapper, type CronFormat } from '@/types'
33
import { genItems } from '@/util'
44
import { describe, expect, it } from 'vitest'
55

6-
const r = (min: number, max: number) => {
7-
return new FieldWrapper({ id: 'fieldId', items: genItems(min, max) })
6+
const r = (min: number, max: number, format: CronFormat = 'crontab') => {
7+
return new FieldWrapper({ id: 'fieldId', items: genItems(min, max) }, { format })
88
}
99

1010
describe('segments', () => {
@@ -23,6 +23,7 @@ describe('segments', () => {
2323
expect(cronToArray('*/10', r(1, 10))).toEqual([1])
2424
expect(cronToArray('2-6/2', r(1, 10))).toEqual([2, 4, 6])
2525
expect(cronToArray('3-5/10', r(1, 10))).toEqual([3])
26+
expect(cronToArray('5/2', r(1, 10, 'quartz'))).toEqual([5, 7, 9])
2627

2728
expect(cronToArray('x', r(0, 59))).toBe(null)
2829
expect(cronToArray('1-60', r(0, 59))).toBe(null)
@@ -32,6 +33,7 @@ describe('segments', () => {
3233
expect(cronToArray('*/90', r(1, 10))).toBe(null)
3334
expect(cronToArray('*/11', r(1, 10))).toBe(null)
3435
expect(cronToArray('2-6/11', r(1, 10))).toBe(null)
36+
expect(cronToArray('5/2', r(1, 10))).toEqual(null)
3537
})
3638

3739
it('arrayToSegment', () => {
@@ -48,5 +50,7 @@ describe('segments', () => {
4850
expect(arrayToCron([5, 12, 19, 26], r(5, 30))).toEqual('*/7')
4951
expect(arrayToCron([0, 5, 10], r(0, 20))).toEqual('0-10/5')
5052
expect(arrayToCron([1, 2, 5, 8, 9, 10], r(1, 10))).toEqual('1-2,5,8-10')
53+
expect(arrayToCron([5, 7, 9], r(1, 10, 'quartz'))).toEqual('5/2')
54+
expect(arrayToCron([5, 7, 9], r(1, 10))).toEqual('5-9/2')
5155
})
5256
})
Collapse file

‎core/src/components/__tests__/cron-segment.spec.ts‎

Copy file name to clipboardExpand all lines: core/src/components/__tests__/cron-segment.spec.ts
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ import { nextTick, ref } from 'vue'
77
import { useCronSegment } from '../cron-segment'
88

99
const f = () => {
10-
const fieldDesc = new FieldWrapper({
11-
id: 'month',
12-
items: defaultItems('en').monthItems,
13-
})
10+
const fieldDesc = new FieldWrapper(
11+
{
12+
id: 'month',
13+
items: defaultItems('en').monthItems,
14+
},
15+
{ format: 'crontab' },
16+
)
1417

1518
const period = { id: 'year', value: [] }
1619

Collapse file

‎core/src/components/cron-core.ts‎

Copy file name to clipboardExpand all lines: core/src/components/cron-core.ts
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ export function useCron(options: CronOptions) {
161161
const periodPrefix = ref('')
162162
const periodSuffix = ref('')
163163
const segments = fields.map((f) => {
164-
return useCronSegment({ field: new FieldWrapper(f), l10n, period })
164+
return useCronSegment({ field: new FieldWrapper(f, { format: format }), l10n, period })
165165
})
166166

167167
const segmentMap = new Map(segments.map((s) => [s.id, s]))
Collapse file

‎core/src/cron.ts‎

Copy file name to clipboardExpand all lines: core/src/cron.ts
+21-5Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,20 @@ function _rangeWithStep(n: number, min: number, max: number) {
135135
}
136136
return res
137137
}
138+
139+
function parseRange(s: string, field: FieldWrapper): [number, number] {
140+
if (s === '*') {
141+
return [field.min, field.max]
142+
}
143+
const range = s.split('-').map((s) => parseInt(s))
144+
if (range.length === 1 && field.ctx.format !== 'crontab') {
145+
return [range[0], field.max]
146+
}
147+
return [range[0], range[1]]
148+
}
149+
138150
class StepSegment implements CronSegment {
139-
static re = /^(\*|\d+-\d+)\/\d+$/
151+
static re = /^(\*|\d+(-\d+)?)\/\d+$/
140152

141153
field: FieldWrapper
142154
step: number
@@ -152,14 +164,20 @@ class StepSegment implements CronSegment {
152164

153165
get type() {
154166
const { min, max } = this.field
167+
if (this.field.ctx.format !== 'crontab' && this.start !== min && max - this.end < this.step) {
168+
return FieldPattern.StepFrom
169+
}
155170
if (this.start !== min || max - this.end >= this.step) {
156171
return FieldPattern.RangeStep
157172
}
158173
return FieldPattern.Step
159174
}
160175

161176
toCron() {
162-
if (this.type == FieldPattern.RangeStep) {
177+
if (this.type === FieldPattern.StepFrom) {
178+
return `${this.start}/${this.step}`
179+
}
180+
if (this.type === FieldPattern.RangeStep) {
163181
return `${this.start}-${this.end}/${this.step}`
164182
}
165183
return `*/${this.step}`
@@ -189,9 +207,7 @@ class StepSegment implements CronSegment {
189207
return null
190208
}
191209

192-
const range = str.split('-').map((s) => parseInt(s))
193-
const min = rangeStr == '*' ? field.min : range[0]
194-
const max = rangeStr == '*' ? field.max : range[1]
210+
const [min, max] = parseRange(rangeStr, field)
195211

196212
if (_rangeWithStep(step, min, max).length == 0) {
197213
return null
Collapse file

‎core/src/locale/en.ts‎

Copy file name to clipboardExpand all lines: core/src/locale/en.ts
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@ const locale: Localization = {
1111
range: { text: '{{start.text}}-{{end.text}}' },
1212
step: { text: 'every {{step.value}}' },
1313
rangeStep: { text: '{{start.text}}-{{end.text}}/{{step.value}}' },
14+
stepFrom: { text: '{{start.text}}/{{step.value}}' },
1415
},
1516
month: {
1617
'*': { prefix: 'in' },
1718
value: { text: '{{value.alt}}' },
1819
range: { text: '{{start.alt}}-{{end.alt}}' },
1920
rangeStep: { text: '{{start.alt}}-{{end.alt}}/{{step.value}}' },
21+
stepFrom: { text: '{{start.alt}}/{{step.value}}' },
2022
},
2123
day: {
2224
'*': { prefix: 'on' },
@@ -30,6 +32,7 @@ const locale: Localization = {
3032
value: { text: '{{value.alt}}' },
3133
range: { text: '{{start.alt}}-{{end.alt}}' },
3234
rangeStep: { text: '{{start.alt}}-{{end.alt}}/{{step.value}}' },
35+
stepFrom: { text: '{{start.alt}}/{{step.value}}' },
3336
noSpecific: {
3437
text: 'no specific day of the week',
3538
},
Collapse file

‎core/src/types.ts‎

Copy file name to clipboardExpand all lines: core/src/types.ts
+13-7Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@ export type SegmentFromArray = (arr: number[], field: FieldWrapper) => CronSegme
1515
export type SegmentFromString = (str: string, field: FieldWrapper) => CronSegment | null
1616

1717
export enum FieldPattern {
18-
Any = 'any',
19-
Value = 'value',
20-
Range = 'range',
21-
Step = 'step',
22-
RangeStep = 'rangeStep',
18+
Any = 'any', // *
19+
Value = 'value', // a
20+
Range = 'range', // a-b
21+
Step = 'step', // */x
22+
StepFrom = `stepFrom`, // a/x
23+
RangeStep = 'rangeStep', // a-b/x
2324
Combined = 'combined',
24-
NoSpecific = 'noSpecific',
25+
NoSpecific = 'noSpecific', // ?
2526
}
2627

2728
export enum TextPosition {
@@ -61,12 +62,17 @@ export interface Period {
6162
text?: string
6263
}
6364

65+
interface FieldContext {
66+
format: CronFormat
67+
}
6468
export class FieldWrapper {
6569
field: Field
6670
itemMap: Record<number, FieldItem>
71+
ctx: FieldContext
6772

68-
constructor(field: Field) {
73+
constructor(field: Field, ctx: FieldContext) {
6974
this.field = field
75+
this.ctx = ctx
7076

7177
this.itemMap = this.field.items.reduce(
7278
(acc, item) => {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.