mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2025-12-05 12:35:47 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c76ca1798e | |||
| 58917c6458 | |||
| 5ef6134d9f | |||
| b9237e13c9 | |||
| 17971ed8fb | |||
| 505108d2dd | |||
| 094284562d |
@@ -1,5 +1,13 @@
|
||||
# Changelog
|
||||
|
||||
## 2.6.1
|
||||
|
||||
* Fixes in parsing of string parts
|
||||
|
||||
## 2.6.0
|
||||
|
||||
* Fix of `doOnceTz` behaviour: now it will use local time as utc time to get next waking up time
|
||||
|
||||
## 2.5.1
|
||||
|
||||
* 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))
|
||||
|
||||
@@ -36,5 +36,5 @@ androidx_work_version=2.10.0
|
||||
|
||||
## Common
|
||||
|
||||
version=2.5.1
|
||||
android_code_version=43
|
||||
version=2.6.1
|
||||
android_code_version=45
|
||||
|
||||
@@ -35,6 +35,8 @@ suspend inline fun <T> KronScheduler.doOnceLocal(block: (DateTime) -> T): T = do
|
||||
/**
|
||||
* Execute [block] once at the [KronScheduler.next] time and return result of [block] calculation.
|
||||
*
|
||||
* WARNING!!! This method will use local time instead of utc
|
||||
*
|
||||
* WARNING!!! If you want to launch it in parallel, you must do this explicitly.
|
||||
*
|
||||
* WARNING!!! In case if [KronScheduler.next] of [this] instance will return null, [block] will be called immediatelly
|
||||
@@ -42,7 +44,7 @@ suspend inline fun <T> KronScheduler.doOnceLocal(block: (DateTime) -> T): T = do
|
||||
suspend inline fun <T> KronScheduler.doOnceTz(noinline block: suspend (DateTimeTz) -> T): T {
|
||||
val time = when (this) {
|
||||
is KronSchedulerTz -> nextOrNowWithOffset()
|
||||
else -> nextOrNow().local
|
||||
else -> nextTimeZoned() ?: DateTimeTz.nowLocal()
|
||||
}
|
||||
delay((time - DateTimeTz.nowLocal()).millisecondsLong)
|
||||
return block(time)
|
||||
|
||||
@@ -41,53 +41,80 @@ private fun <T> createSimpleScheduler(from: String, dataRange: IntRange, dataCon
|
||||
* FSM for parsing of incoming data. If at the end of parsing it have non-null state and string is not empty, data passed check
|
||||
*
|
||||
* 1.
|
||||
* * \\d -> 1
|
||||
* * \\* -> 2
|
||||
* * \\- -> 5
|
||||
* * , -> 1
|
||||
* * m -> 6
|
||||
* * o -> 7
|
||||
* * w -> 7
|
||||
* * "\\d" -> 2
|
||||
* * "\\*" -> 4
|
||||
* * "f" -> 7
|
||||
* * "l" -> 7
|
||||
* * "/" -> 6
|
||||
* 2.
|
||||
* * / -> 3
|
||||
* * "\\d" -> 2
|
||||
* * "/" -> 6
|
||||
* * "," -> 1
|
||||
* * "-" -> 3
|
||||
* * "m" -> 9
|
||||
* * "o" -> 10
|
||||
* * "w" -> 10
|
||||
* 3.
|
||||
* * \\d -> 3
|
||||
* * \\* -> 4
|
||||
* * "l" -> 7
|
||||
* * "\\d" -> 8
|
||||
* 4.
|
||||
* * , -> 1
|
||||
* * "/" -> 6
|
||||
* * "," -> 1
|
||||
* 5.
|
||||
* * \\d -> 5
|
||||
* * , -> 1
|
||||
* * "/" -> 6
|
||||
* 6.
|
||||
* * s -> 7
|
||||
* 7. Empty, end of parse
|
||||
* * "\\d" -> 8
|
||||
* * "\\*" -> 7
|
||||
* 7.
|
||||
* * "," -> 1
|
||||
* 8.
|
||||
* * "\\d" -> 8
|
||||
* * "," -> 1
|
||||
* 9.
|
||||
* * "s" -> 10 // end of ms
|
||||
* 10. Empty, end of parse
|
||||
*/
|
||||
private val checkIncomingPartTransitionsMap = listOf(
|
||||
listOf(
|
||||
Regex("\\d") to 0,
|
||||
Regex("\\*") to 1,
|
||||
Regex("-") to 4,
|
||||
Regex(",") to 0,
|
||||
Regex("m") to 5,
|
||||
Regex("o") to 6,
|
||||
Regex("w") to 6,
|
||||
),
|
||||
listOf(
|
||||
Regex("/") to 2,
|
||||
),
|
||||
listOf(
|
||||
Regex("\\d") to 2,
|
||||
listOf( // 0
|
||||
Regex("\\d") to 1,
|
||||
Regex("\\*") to 3,
|
||||
Regex("f") to 6,
|
||||
Regex("l") to 6,
|
||||
Regex("/") to 5,
|
||||
),
|
||||
listOf(
|
||||
listOf( // 1
|
||||
Regex("\\d") to 1,
|
||||
Regex("/") to 5,
|
||||
Regex(",") to 0,
|
||||
Regex("-") to 2,
|
||||
Regex("m") to 8,
|
||||
Regex("o") to 9,
|
||||
Regex("w") to 9,
|
||||
),
|
||||
listOf( // 2
|
||||
Regex("l") to 6,
|
||||
Regex("\\d") to 7,
|
||||
),
|
||||
listOf( // 3
|
||||
Regex("/") to 5,
|
||||
Regex(",") to 0,
|
||||
),
|
||||
listOf(
|
||||
Regex("\\d") to 4,
|
||||
listOf( // 4
|
||||
Regex("/") to 5,
|
||||
),
|
||||
listOf( // 5
|
||||
Regex("\\d") to 7,
|
||||
Regex("\\*") to 6,
|
||||
),
|
||||
listOf( // 6
|
||||
Regex(",") to 0,
|
||||
),
|
||||
listOf(
|
||||
Regex("s") to 6, // end of ms
|
||||
listOf( // 7
|
||||
Regex("\\d") to 7,
|
||||
Regex(",") to 0,
|
||||
),
|
||||
listOf( // 8
|
||||
Regex("s") to 9, // end of ms
|
||||
),
|
||||
listOf(), // empty state, end of parsing
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.inmo.krontab.utils
|
||||
|
||||
import korlibs.time.*
|
||||
import dev.inmo.krontab.KronSchedulerTz
|
||||
import dev.inmo.krontab.KrontabTemplate
|
||||
import dev.inmo.krontab.buildSchedule
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
@@ -11,73 +12,51 @@ import kotlin.test.*
|
||||
@ExperimentalCoroutinesApi
|
||||
@FlowPreview
|
||||
class StringParseTest {
|
||||
@Test
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() {
|
||||
val kronScheduler = buildSchedule("*/1 * * * *")
|
||||
private fun makeSimpleEverySecondTest(template: KrontabTemplate) {
|
||||
val kronScheduler = buildSchedule(template)
|
||||
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val mustBeCollected = 10
|
||||
var collected = 0
|
||||
var previousTime: DateTime? = null
|
||||
flow.takeWhile {
|
||||
collected < mustBeCollected
|
||||
}.collect {
|
||||
previousTime ?.let { previousTime ->
|
||||
assertEquals(previousTime + 1.seconds, it)
|
||||
}
|
||||
previousTime = it
|
||||
collected++
|
||||
}
|
||||
assertEquals(mustBeCollected, collected)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() {
|
||||
makeSimpleEverySecondTest("*/1 * * * *")
|
||||
}
|
||||
@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)
|
||||
val templatesFirstReplacers = listOf(
|
||||
"*/1",
|
||||
"*",
|
||||
"/1",
|
||||
"f,/1",
|
||||
)
|
||||
templatesFirstReplacers.forEach { replacer ->
|
||||
makeSimpleEverySecondTest("$replacer * * * * ")
|
||||
}
|
||||
}
|
||||
@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)
|
||||
}
|
||||
makeSimpleEverySecondTest(" sdf */1 * * * oo * ")
|
||||
}
|
||||
@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)
|
||||
}
|
||||
makeSimpleEverySecondTest(" sdf */1 ")
|
||||
}
|
||||
@Test
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
|
||||
@@ -88,9 +67,14 @@ class StringParseTest {
|
||||
runTest {
|
||||
val mustBeCollected = 10
|
||||
var collected = 0
|
||||
var previousTime: DateTime? = null
|
||||
flow.takeWhile {
|
||||
collected < mustBeCollected
|
||||
}.collect {
|
||||
previousTime ?.let { previousTime ->
|
||||
assertEquals(previousTime.copy(milliseconds = 500) + 1.seconds, it)
|
||||
}
|
||||
previousTime = it
|
||||
collected++
|
||||
}
|
||||
assertEquals(mustBeCollected, collected)
|
||||
|
||||
Reference in New Issue
Block a user