mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2024-11-22 16:23:55 +00:00
fix of #126
This commit is contained in:
parent
ca5794726f
commit
e4b3a5059a
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
## 2.5.0
|
## 2.5.0
|
||||||
|
|
||||||
|
* Add cleaning up of incoming template, which must remove all malformed parts from string template (fix of [#126](https://github.com/InsanusMokrassar/krontab/issues/126))
|
||||||
|
* Add support of insufficient amount of arguments (fix of [#126](https://github.com/InsanusMokrassar/krontab/issues/126))
|
||||||
* `Version`:
|
* `Version`:
|
||||||
* `Kotlin`: `2.0.20`
|
* `Kotlin`: `2.0.20`
|
||||||
* `AndroidXWork`: `2.10.0`
|
* `AndroidXWork`: `2.10.0`
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.krontab
|
package dev.inmo.krontab
|
||||||
|
|
||||||
|
import dev.inmo.krontab.internal.*
|
||||||
import dev.inmo.krontab.internal.CronDateTimeScheduler
|
import dev.inmo.krontab.internal.CronDateTimeScheduler
|
||||||
import dev.inmo.krontab.internal.CronDateTimeSchedulerTz
|
import dev.inmo.krontab.internal.CronDateTimeSchedulerTz
|
||||||
import dev.inmo.krontab.internal.createKronScheduler
|
import dev.inmo.krontab.internal.createKronScheduler
|
||||||
@ -94,27 +95,37 @@ value class KrontabConfig(
|
|||||||
var dayOfWeekParsed: Array<Byte>? = null
|
var dayOfWeekParsed: Array<Byte>? = null
|
||||||
var yearParsed: Array<Int>? = null
|
var yearParsed: Array<Int>? = null
|
||||||
var millisecondsParsed: Array<Short>? = null
|
var millisecondsParsed: Array<Short>? = null
|
||||||
val (secondsSource, minutesSource, hoursSource, dayOfMonthSource, monthSource) = template.split(" ").also {
|
val (secondsSource, minutesSource, hoursSource, dayOfMonthSource, monthSource) = template
|
||||||
listOfNotNull(
|
.split(Regex("\\s"))
|
||||||
it.getOrNull(5),
|
.filter { it.matches(KrontabConfigPartRegex) } // filter garbage from string
|
||||||
it.getOrNull(6),
|
.let {
|
||||||
it.getOrNull(7),
|
if (it.size < 5) { // reconstruction in case of insufficient arguments; 5 is amount of required arguments out of latest also code
|
||||||
it.getOrNull(8)
|
it + (it.size until 5).map { "*" }
|
||||||
).forEach {
|
} else {
|
||||||
val offsetFromString = parseOffset(it)
|
it
|
||||||
val dayOfWeekFromString = parseWeekDay(it)
|
}
|
||||||
val millisecondsFromString = parseMilliseconds(it)
|
}
|
||||||
offsetParsed = offsetParsed ?: offsetFromString
|
.also {
|
||||||
dayOfWeekParsed = dayOfWeekParsed ?: dayOfWeekFromString
|
listOfNotNull(
|
||||||
millisecondsParsed = millisecondsParsed ?: millisecondsFromString
|
it.getOrNull(5),
|
||||||
when {
|
it.getOrNull(6),
|
||||||
dayOfWeekFromString != null || offsetFromString != null || millisecondsFromString != null -> return@forEach
|
it.getOrNull(7),
|
||||||
yearParsed == null -> {
|
it.getOrNull(8)
|
||||||
yearParsed = parseYears(it)
|
).forEach {
|
||||||
|
val offsetFromString = parseOffset(it)
|
||||||
|
val dayOfWeekFromString = parseWeekDay(it)
|
||||||
|
val millisecondsFromString = parseMilliseconds(it)
|
||||||
|
offsetParsed = offsetParsed ?: offsetFromString
|
||||||
|
dayOfWeekParsed = dayOfWeekParsed ?: dayOfWeekFromString
|
||||||
|
millisecondsParsed = millisecondsParsed ?: millisecondsFromString
|
||||||
|
when {
|
||||||
|
dayOfWeekFromString != null || offsetFromString != null || millisecondsFromString != null -> return@forEach
|
||||||
|
yearParsed == null -> {
|
||||||
|
yearParsed = parseYears(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val secondsParsed = parseSeconds(secondsSource)
|
val secondsParsed = parseSeconds(secondsSource)
|
||||||
val minutesParsed = parseMinutes(minutesSource)
|
val minutesParsed = parseMinutes(minutesSource)
|
||||||
@ -162,4 +173,9 @@ value class KrontabConfig(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val spacesRegex = Regex("\\s")
|
||||||
|
val numberRegex = Regex("\\d+")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,10 @@ private fun <T> createSimpleScheduler(from: String, dataRange: IntRange, dataCon
|
|||||||
return results.map(dataConverter)
|
return results.map(dataConverter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val KrontabPartNumberRegexString = "((\\d+\\-\\d+)|([\\d\\*]+(/[\\d\\*]+)?))"
|
||||||
|
internal val KrontabPartsNumberRegexString = "$KrontabPartNumberRegexString(,$KrontabPartNumberRegexString)*"
|
||||||
|
internal val KrontabConfigPartRegex = Regex("(($KrontabPartsNumberRegexString+)|(\\d+o)|($KrontabPartsNumberRegexString+w)|($KrontabPartsNumberRegexString+ms))")
|
||||||
|
|
||||||
internal fun parseWeekDay(from: String?) = from ?.let { if (it.endsWith("w")) createSimpleScheduler(it.removeSuffix("w"), dayOfWeekRange, intToByteConverter) ?.toTypedArray() else null }
|
internal fun parseWeekDay(from: String?) = from ?.let { if (it.endsWith("w")) createSimpleScheduler(it.removeSuffix("w"), dayOfWeekRange, intToByteConverter) ?.toTypedArray() else null }
|
||||||
internal fun parseOffset(from: String?) = from ?.let { if (it.endsWith("o")) it.removeSuffix("o").toIntOrNull() else null }
|
internal fun parseOffset(from: String?) = from ?.let { if (it.endsWith("o")) it.removeSuffix("o").toIntOrNull() else null }
|
||||||
internal fun parseYears(from: String?) = from ?.let { createSimpleScheduler(from, yearRange, intToIntConverter) ?.toTypedArray() }
|
internal fun parseYears(from: String?) = from ?.let { createSimpleScheduler(from, yearRange, intToIntConverter) ?.toTypedArray() }
|
||||||
|
@ -29,6 +29,57 @@ class StringParseTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
|
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnStringWithWrongAmountOfSpaces() {
|
||||||
|
val kronScheduler = buildSchedule("*/1 * * * * ")
|
||||||
|
|
||||||
|
val flow = kronScheduler.asFlowWithoutDelays()
|
||||||
|
|
||||||
|
runTest {
|
||||||
|
val mustBeCollected = 10
|
||||||
|
var collected = 0
|
||||||
|
flow.takeWhile {
|
||||||
|
collected < mustBeCollected
|
||||||
|
}.collect {
|
||||||
|
collected++
|
||||||
|
}
|
||||||
|
assertEquals(mustBeCollected, collected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnStringWithGarbageInTemplate() {
|
||||||
|
val kronScheduler = buildSchedule(" sdf */1 * * * oo * ")
|
||||||
|
|
||||||
|
val flow = kronScheduler.asFlowWithoutDelays()
|
||||||
|
|
||||||
|
runTest {
|
||||||
|
val mustBeCollected = 10
|
||||||
|
var collected = 0
|
||||||
|
flow.takeWhile {
|
||||||
|
collected < mustBeCollected
|
||||||
|
}.collect {
|
||||||
|
collected++
|
||||||
|
}
|
||||||
|
assertEquals(mustBeCollected, collected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnStringWithInsufficientArgsInTemplate() {
|
||||||
|
val kronScheduler = buildSchedule(" sdf */1 ")
|
||||||
|
|
||||||
|
val flow = kronScheduler.asFlowWithoutDelays()
|
||||||
|
|
||||||
|
runTest {
|
||||||
|
val mustBeCollected = 10
|
||||||
|
var collected = 0
|
||||||
|
flow.takeWhile {
|
||||||
|
collected < mustBeCollected
|
||||||
|
}.collect {
|
||||||
|
collected++
|
||||||
|
}
|
||||||
|
assertEquals(mustBeCollected, collected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
|
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
|
||||||
val kronScheduler = buildSchedule("*/1 * * * * 500ms")
|
val kronScheduler = buildSchedule("*/1 * * * * 500ms")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user