mirror of
https://github.com/InsanusMokrassar/krontab.git
synced 2025-12-05 12:35:47 +00:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a61cd61602 | |||
| 68ed562b19 | |||
| 87b5dfe1aa | |||
| 6a6bfe0552 | |||
| ede47ae664 | |||
| 890ab5b15d | |||
| 5a1ed2f933 | |||
| 7da67386cf | |||
| 7027719fe5 | |||
| a81c7c7c3f | |||
|
|
e5658998d4 | ||
| 6b3cb981ab | |||
| f6518d4d25 | |||
| 97a8f39826 | |||
| 469861f7e3 | |||
| 69305506ce | |||
| 63ea3f0f1a | |||
| 13a8bacb52 | |||
| 9c80e29e71 | |||
| cfd2de8fe9 | |||
| e3490d432e | |||
| 1c95636b71 | |||
| b31a6ab86a |
10
.github/workflows/publishing_packages.yml
vendored
10
.github/workflows/publishing_packages.yml
vendored
@@ -8,18 +8,20 @@ jobs:
|
||||
- uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Fix android 32.0.0 dx
|
||||
continue-on-error: true
|
||||
run: cd /usr/local/lib/android/sdk/build-tools/32.0.0/ && cp d8 dx && cd lib && cp d8.jar dx.jar
|
||||
- name: Update version
|
||||
run: |
|
||||
branch="`echo "${{ github.ref }}" | grep -o "[^/]*$"`"
|
||||
sed -i -e "s/^version=\([0-9\.]*\)/version=\1-branch_$branch-build${{ github.run_number }}/" gradle.properties
|
||||
- name: prebuild
|
||||
run: ./gradlew clean build
|
||||
- name: Publish to Gitea
|
||||
continue-on-error: true
|
||||
run: ./gradlew publishAllPublicationsToGiteaRepository
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||
- name: Publish package
|
||||
continue-on-error: true
|
||||
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository -x signJsPublication -x signJvmPublication -x signKotlinMultiplatformPublication -x signAndroidReleasePublication -x signAndroidDebugPublication -x signAndroidReleasePublication
|
||||
run: ./gradlew --no-parallel publishAllPublicationsToGithubPackagesRepository
|
||||
env:
|
||||
GITHUBPACKAGES_USER: ${{ github.actor }}
|
||||
GITHUBPACKAGES_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,4 +9,6 @@ settings.xml
|
||||
build/
|
||||
out/
|
||||
|
||||
kotlin-js-store/
|
||||
|
||||
local.properties
|
||||
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
@@ -1,5 +1,32 @@
|
||||
# Changelog
|
||||
|
||||
## 1.0.0
|
||||
|
||||
* Versions
|
||||
* `Kotlin`: `1.8.20`
|
||||
* `AndroidXWork`: `2.8.1`
|
||||
|
||||
## 0.10.0
|
||||
|
||||
* New extensions for `KronScheduler`:
|
||||
* `asTzFlowWithoutDelays`/`asFlowWithoutDelays`
|
||||
* `asTzFlowWithDelays`/`asFlowWithDelays`
|
||||
* Old `KronScheduler.asFlow` and `KronScheduler.asTzFlow` temporarily marked as deprecated: after several versions their
|
||||
behaviour will be changed to undelayed one
|
||||
* All the flow extensions now use `cold` non-channel flows. Potentially it should increase performance and decrease memory usage
|
||||
|
||||
## 0.9.0
|
||||
|
||||
* Versions
|
||||
* `Kotlin`: `1.8.10`
|
||||
* `AndroidXWork`: `2.8.0`
|
||||
|
||||
## 0.8.5
|
||||
|
||||
* Project is now available in owner `Gitea`: https://git.inmo.dev/InsanusMokrassar/-/packages/maven/dev.inmo-krontab
|
||||
* `KronSchedulerTz#next` with incoming `DateTime` now will use adjusted local time instead of unadjusted one
|
||||
* `CronDateTimeSchedulerTz#next` with incoming `DateTime` will convert that parameter to internal offset directly
|
||||
|
||||
## 0.8.4
|
||||
|
||||
* Versions
|
||||
|
||||
14
README.md
14
README.md
@@ -1,15 +1,17 @@
|
||||
# krontab
|
||||
|
||||
[](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab)
|
||||
[](https://github.com/InsanusMokrassar/krontab/actions/workflows/publishing_packages.yml)
|
||||
|
||||

|
||||
[](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab)
|
||||
|
||||
[](https://inmodev_chat.t.me)
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
[](https://insanusmokrassar.github.io/krontab/)
|
||||
[](https://bookstack.inmo.dev/books/krontab)
|
||||
|
||||
|
||||
Library was created to give oppotunity to launch some things from time to time according to some schedule in
|
||||
runtime of applications.
|
||||
|
||||
@@ -25,7 +27,7 @@ Anyway, to start some action from time to time you will need to use one of exten
|
||||
```kotlin
|
||||
val kronScheduler = /* creating of KronScheduler instance */;
|
||||
|
||||
kronScheuler.doWhile {
|
||||
kronScheduler.doWhile {
|
||||
// some action
|
||||
true // true - repeat on next time
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ buildscript {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.github.breadmoirai:github-release:$github_release_plugin_version"
|
||||
classpath "com.getkeepsafe.dexcount:dexcount-gradle-plugin:$dexcount_version"
|
||||
classpath 'com.android.tools.build:gradle:7.0.4'
|
||||
classpath "com.android.tools.build:gradle:$android_gradle_version"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ kotlin {
|
||||
android {
|
||||
publishAllLibraryVariants()
|
||||
}
|
||||
linuxX64()
|
||||
|
||||
|
||||
sourceSets {
|
||||
@@ -79,6 +80,7 @@ kotlin {
|
||||
dependencies {
|
||||
implementation kotlin('test-common')
|
||||
implementation kotlin('test-annotations-common')
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlin_coroutines_version"
|
||||
}
|
||||
}
|
||||
jvmTest {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
org.gradle.jvmargs=-Xmx512m
|
||||
kotlin.code.style=official
|
||||
org.gradle.parallel=true
|
||||
kotlin.js.generate.externals=true
|
||||
@@ -8,10 +9,10 @@ android.useAndroidX=true
|
||||
android.enableJetifier=false
|
||||
|
||||
|
||||
kotlin_version=1.7.22
|
||||
kotlin_version=1.8.20
|
||||
kotlin_coroutines_version=1.6.4
|
||||
|
||||
dokka_version=1.7.20
|
||||
dokka_version=1.8.10
|
||||
|
||||
klockVersion=3.4.0
|
||||
|
||||
@@ -21,17 +22,18 @@ github_release_plugin_version=2.4.1
|
||||
|
||||
## Android
|
||||
|
||||
android_gradle_version=7.4.2
|
||||
android_minSdkVersion=21
|
||||
android_compileSdkVersion=33
|
||||
android_buildToolsVersion=33.0.0
|
||||
dexcount_version=3.1.0
|
||||
android_buildToolsVersion=33.0.2
|
||||
dexcount_version=4.0.0
|
||||
junit_version=4.12
|
||||
test_ext_junit_version=1.1.3
|
||||
espresso_core=3.4.0
|
||||
|
||||
androidx_work_version=2.7.1
|
||||
androidx_work_version=2.8.1
|
||||
|
||||
## Common
|
||||
|
||||
version=0.8.4
|
||||
android_code_version=21
|
||||
version=1.0.0
|
||||
android_code_version=25
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","includeGpgSigning":true,"developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}]}}
|
||||
{"licenses":[{"id":"Apache-2.0","title":"Apache Software License 2.0","url":"https://github.com/InsanusMokrassar/krontab/blob/master/LICENSE"}],"mavenConfig":{"name":"Krontab","description":"It is an analog of crontab util for Kotlin Coroutines","url":"https://github.com/InsanusMokrassar/krontab","vcsUrl":"https://github.com/InsanusMokrassar/krontab.git","developers":[{"id":"InsanusMokrassar","name":"Ovsiannikov Aleksei","eMail":"ovsyannikov.alexey95@gmail.com"}],"repositories":[{"name":"GithubPackages","url":"https://maven.pkg.github.com/InsanusMokrassar/krontab"},{"name":"Gitea","url":"https://git.inmo.dev/api/packages/InsanusMokrassar/maven","credsType":{"type":"dev.inmo.kmppscriptbuilder.core.models.MavenPublishingRepository.CredentialsType.HttpHeaderCredentials","headerName":"Authorization","headerValueProperty":"GITEA_TOKEN"}},{"name":"sonatype","url":"https://oss.sonatype.org/service/local/staging/deploy/maven2/"}],"gpgSigning":{"type":"dev.inmo.kmppscriptbuilder.core.models.GpgSigning.Optional"}}}
|
||||
@@ -1,5 +1,4 @@
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: 'signing'
|
||||
|
||||
task javadocsJar(type: Jar) {
|
||||
classifier = 'javadoc'
|
||||
@@ -43,27 +42,58 @@ publishing {
|
||||
maven {
|
||||
name = "GithubPackages"
|
||||
url = uri("https://maven.pkg.github.com/InsanusMokrassar/krontab")
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('GITHUBPACKAGES_USER') ? project.property('GITHUBPACKAGES_USER') : System.getenv('GITHUBPACKAGES_USER')
|
||||
password = project.hasProperty('GITHUBPACKAGES_PASSWORD') ? project.property('GITHUBPACKAGES_PASSWORD') : System.getenv('GITHUBPACKAGES_PASSWORD')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (project.hasProperty('GITEA_TOKEN') || System.getenv('GITEA_TOKEN') != null) {
|
||||
maven {
|
||||
name = "Gitea"
|
||||
url = uri("https://git.inmo.dev/api/packages/InsanusMokrassar/maven")
|
||||
|
||||
credentials(HttpHeaderCredentials) {
|
||||
name = "Authorization"
|
||||
value = project.hasProperty('GITEA_TOKEN') ? project.property('GITEA_TOKEN') : System.getenv('GITEA_TOKEN')
|
||||
}
|
||||
|
||||
authentication {
|
||||
header(HttpHeaderAuthentication)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ((project.hasProperty('SONATYPE_USER') || System.getenv('SONATYPE_USER') != null) && (project.hasProperty('SONATYPE_PASSWORD') || System.getenv('SONATYPE_PASSWORD') != null)) {
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/")
|
||||
|
||||
credentials {
|
||||
username = project.hasProperty('SONATYPE_USER') ? project.property('SONATYPE_USER') : System.getenv('SONATYPE_USER')
|
||||
password = project.hasProperty('SONATYPE_PASSWORD') ? project.property('SONATYPE_PASSWORD') : System.getenv('SONATYPE_PASSWORD')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
sign publishing.publications
|
||||
|
||||
if (project.hasProperty("signing.gnupg.keyName")) {
|
||||
apply plugin: 'signing'
|
||||
|
||||
signing {
|
||||
useGpgCmd()
|
||||
|
||||
sign publishing.publications
|
||||
}
|
||||
|
||||
task signAll {
|
||||
tasks.withType(Sign).forEach {
|
||||
dependsOn(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.soywiz.klock.DateTimeTz
|
||||
interface KronSchedulerTz : KronScheduler {
|
||||
suspend fun next(relatively: DateTimeTz): DateTimeTz?
|
||||
|
||||
override suspend fun next(relatively: DateTime): DateTime? = next(relatively.localUnadjusted) ?.local
|
||||
override suspend fun next(relatively: DateTime): DateTime? = next(relatively.local) ?.local
|
||||
}
|
||||
|
||||
suspend fun KronSchedulerTz.nextOrRelative(relatively: DateTimeTz): DateTimeTz = next(relatively) ?: getAnyNext(
|
||||
@@ -31,4 +31,4 @@ suspend fun KronScheduler.next(relatively: DateTimeTz) = if (this is KronSchedul
|
||||
this.next(relatively.local) ?.toOffsetUnadjusted(relatively.offset)
|
||||
}
|
||||
|
||||
suspend fun KronScheduler.nextTimeZoned() = next(DateTime.now().local)
|
||||
suspend fun KronScheduler.nextTimeZoned() = next(DateTime.now().local)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.inmo.krontab.internal
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import com.soywiz.klock.DateTimeTz
|
||||
import com.soywiz.klock.TimezoneOffset
|
||||
import dev.inmo.krontab.KronScheduler
|
||||
@@ -18,6 +19,10 @@ internal data class CronDateTimeSchedulerTz internal constructor(
|
||||
val dateTimeWithActualOffset = relatively.toOffset(offset).local
|
||||
return cronDateTime.toNearDateTime(dateTimeWithActualOffset) ?.toOffsetUnadjusted(offset) ?.toOffset(relatively.offset)
|
||||
}
|
||||
|
||||
override suspend fun next(relatively: DateTime): DateTime? {
|
||||
return next(relatively.toOffset(offset)) ?.utc
|
||||
}
|
||||
}
|
||||
|
||||
internal fun mergeCronDateTimeSchedulers(
|
||||
|
||||
@@ -2,35 +2,90 @@ package dev.inmo.krontab.utils
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
import com.soywiz.klock.DateTimeTz
|
||||
import dev.inmo.krontab.*
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import com.soywiz.klock.milliseconds
|
||||
import dev.inmo.krontab.KronScheduler
|
||||
import dev.inmo.krontab.next
|
||||
import kotlinx.coroutines.currentCoroutineContext
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.channelFlow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
/**
|
||||
* This [Flow] will trigger emitting each near time which will be returned from [this] [KronScheduler] with attention to
|
||||
* time zones
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* @see channelFlow
|
||||
* @see KronSchedulerTz.doInfinityTz
|
||||
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
|
||||
* be completed
|
||||
*
|
||||
* @param since Will be used as the first parameter for [KronScheduler.next] fun
|
||||
*/
|
||||
@FlowPreview
|
||||
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = channelFlow {
|
||||
doInfinityTz {
|
||||
send(it)
|
||||
fun KronScheduler.asTzFlowWithoutDelays(since: DateTimeTz = DateTime.nowLocal()): Flow<DateTimeTz> = flow {
|
||||
var previous = since
|
||||
while (currentCoroutineContext().isActive) {
|
||||
val next = next(previous) ?: break
|
||||
emit(next)
|
||||
previous = next + 1.milliseconds
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a map for [asTzFlow] and will works the same but return flow with [DateTime]s
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* @see channelFlow
|
||||
* @see KronScheduler.doInfinity
|
||||
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
|
||||
*/
|
||||
@FlowPreview
|
||||
fun KronScheduler.asFlow(): Flow<DateTime> = channelFlow {
|
||||
doInfinity {
|
||||
send(it)
|
||||
fun KronScheduler.asTzFlowWithDelays(): Flow<DateTimeTz> = asTzFlowWithoutDelays().onEach { futureHappenTime ->
|
||||
val now = DateTime.nowLocal()
|
||||
|
||||
delay((futureHappenTime - now).millisecondsLong)
|
||||
}
|
||||
|
||||
/**
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* This [Flow] will use [asTzFlowWithoutDelays], but stop on each time until this time will happen
|
||||
*/
|
||||
@Deprecated(
|
||||
"Behaviour will be changed. In some of near versions this flow will not delay executions",
|
||||
ReplaceWith("this.asTzFlowWithDelays()", "dev.inmo.krontab.utils.asTzFlowWithDelays")
|
||||
)
|
||||
fun KronScheduler.asTzFlow(): Flow<DateTimeTz> = asTzFlowWithDelays()
|
||||
|
||||
/**
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* Will emit all the [KronScheduler.next] as soon as possible. In case [KronScheduler.next] return null, flow will
|
||||
* be completed
|
||||
*
|
||||
* @param since Will be used as the first parameter for [KronScheduler.next] fun
|
||||
*/
|
||||
fun KronScheduler.asFlowWithoutDelays(since: DateTime = DateTime.now()): Flow<DateTime> = flow {
|
||||
var previous = since
|
||||
while (currentCoroutineContext().isActive) {
|
||||
val next = next(previous) ?: break
|
||||
emit(next)
|
||||
previous = next + 1.milliseconds
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* This [Flow] will use [asFlowWithoutDelays], but stop on each time until this time will happen
|
||||
*/
|
||||
fun KronScheduler.asFlowWithDelays(): Flow<DateTime> = asFlowWithoutDelays().onEach { futureHappenTime ->
|
||||
val now = DateTime.now()
|
||||
|
||||
delay((futureHappenTime - now).millisecondsLong)
|
||||
}
|
||||
|
||||
/**
|
||||
* **This flow is [cold](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/-flow/)**
|
||||
*
|
||||
* This [Flow] will use [asFlowWithDelays], but stop on each time until this time will happen
|
||||
*/
|
||||
@Deprecated(
|
||||
"Behaviour will be changed. In some of near versions this flow will not delay executions",
|
||||
ReplaceWith("this.asFlowWithDelays()", "dev.inmo.krontab.utils.asFlowWithDelays")
|
||||
)
|
||||
fun KronScheduler.asFlow(): Flow<DateTime> = asFlowWithDelays()
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.inmo.krontab.utils
|
||||
import com.soywiz.klock.DateTime
|
||||
import com.soywiz.klock.days
|
||||
import dev.inmo.krontab.buildSchedule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.*
|
||||
|
||||
class CheckMonthsAndDaysCorrectWork {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package dev.inmo.krontab.utils
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
fun CoroutineScope.createFailJob(forTimeMillis: Long) = launch {
|
||||
delay(forTimeMillis)
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package dev.inmo.krontab.utils
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
/**
|
||||
* Workaround to use suspending functions in unit tests
|
||||
*/
|
||||
expect fun runTest(block: suspend (scope : CoroutineScope) -> Unit)
|
||||
@@ -2,8 +2,8 @@ package dev.inmo.krontab.utils
|
||||
|
||||
import dev.inmo.krontab.builder.buildSchedule
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@@ -18,7 +18,7 @@ class SchedulerFlowTests {
|
||||
}
|
||||
}
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val mustBeCollected = 10
|
||||
@@ -40,14 +40,14 @@ class SchedulerFlowTests {
|
||||
}
|
||||
}
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val testsCount = 10
|
||||
val failJob = it.createFailJob((testsCount * 2) * 1000L)
|
||||
val failJob = createFailJob((testsCount * 2) * 1000L)
|
||||
val mustBeCollected = 10
|
||||
val answers = (0 until testsCount).map { _ ->
|
||||
it.async {
|
||||
async {
|
||||
var collected = 0
|
||||
flow.takeWhile {
|
||||
collected < mustBeCollected
|
||||
|
||||
@@ -4,9 +4,8 @@ import com.soywiz.klock.*
|
||||
import dev.inmo.krontab.KronSchedulerTz
|
||||
import dev.inmo.krontab.buildSchedule
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlin.math.floor
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.*
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
@@ -16,7 +15,7 @@ class StringParseTest {
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondBuiltOnString() {
|
||||
val kronScheduler = buildSchedule("*/1 * * * *")
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val mustBeCollected = 10
|
||||
@@ -33,7 +32,7 @@ class StringParseTest {
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondWhenMillisIsHalfOfSecondBuiltOnString() {
|
||||
val kronScheduler = buildSchedule("*/1 * * * * 500ms")
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val mustBeCollected = 10
|
||||
@@ -51,14 +50,14 @@ class StringParseTest {
|
||||
fun testThatFlowIsCorrectlyWorkEverySecondWithMuchOfEmittersBuiltOnString() {
|
||||
val kronScheduler = buildSchedule("*/1 * * * *")
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val testsCount = 10
|
||||
val failJob = it.createFailJob((testsCount * 2) * 1000L)
|
||||
val failJob = createFailJob((testsCount * 2) * 1000L)
|
||||
val mustBeCollected = 10
|
||||
val answers = (0 until testsCount).map { _ ->
|
||||
it.async {
|
||||
async {
|
||||
var collected = 0
|
||||
flow.takeWhile {
|
||||
collected < mustBeCollected
|
||||
@@ -81,7 +80,7 @@ class StringParseTest {
|
||||
val rangesEnds = listOf(0 to 5, 30 to 35)
|
||||
val kronScheduler = buildSchedule("${rangesEnds.joinToString(",") { "${it.first}-${it.second}" }} * * * *")
|
||||
|
||||
val flow = kronScheduler.asFlow()
|
||||
val flow = kronScheduler.asFlowWithoutDelays()
|
||||
|
||||
runTest {
|
||||
val ranges = rangesEnds.map { it.first .. it.second }.flatten().distinct().toMutableList()
|
||||
@@ -91,7 +90,10 @@ class StringParseTest {
|
||||
flow.takeWhile { ranges.isNotEmpty() }.collect {
|
||||
ranges.remove(it.seconds)
|
||||
collected++
|
||||
assertTrue(collected <= expectedCollects)
|
||||
assertTrue(
|
||||
collected <= expectedCollects,
|
||||
"Expected value should be less than $expectedCollects, but was $collected. Ranges state: $ranges"
|
||||
)
|
||||
}
|
||||
assertEquals(expectedCollects, collected)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package dev.inmo.krontab.utils
|
||||
import com.soywiz.klock.*
|
||||
import dev.inmo.krontab.builder.buildSchedule
|
||||
import dev.inmo.krontab.next
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package dev.inmo.krontab.utils
|
||||
|
||||
import com.soywiz.klock.*
|
||||
import dev.inmo.krontab.builder.buildSchedule
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.math.ceil
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
package dev.inmo.krontab.utils
|
||||
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
actual fun runTest(block: suspend (scope : CoroutineScope) -> Unit): dynamic = GlobalScope.promise { block(this) }
|
||||
@@ -1,9 +0,0 @@
|
||||
package dev.inmo.krontab.utils
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
/**
|
||||
* Workaround to use suspending functions in unit tests
|
||||
*/
|
||||
actual fun runTest(block: suspend (scope: CoroutineScope) -> Unit) = runBlocking(block = block)
|
||||
Reference in New Issue
Block a user