From 89360206026616db913bae2046041bd1913bba5a Mon Sep 17 00:00:00 2001 From: Sergey Date: Sun, 1 May 2022 21:23:36 +0200 Subject: [PATCH] Feature/short names instead numbers (#6) * Add building for Starting At week day setup by short name * Extend At function * Fix tests * Add Starting At short week day name parsing support * Add tests * Extend On function * Fix and add tests * Add Of Month short week day name parsing support * Add tests * Increase version * Update README --- README.md | 10 ++++---- build.gradle | 2 +- .../kcron/builders/DaysOfWeekBuilder.kt | 24 ++++++++++++++----- .../kotlin/com/ucasoft/kcron/extensions/At.kt | 9 +++++-- .../kotlin/com/ucasoft/kcron/extensions/On.kt | 9 +++++-- .../kcron/parsers/AnySpecificEveryAtParser.kt | 11 +++++++-- .../kcron/parsers/AnySpecificEveryParser.kt | 2 +- .../kcron/parsers/AnySpecificParser.kt | 2 +- .../ucasoft/kcron/parsers/DaysOfWeekParser.kt | 2 +- .../ucasoft/kcron/builders/BuilderTests.kt | 16 ++++++------- .../kcron/builders/DaysOfWeekBuilderTests.kt | 4 ++++ .../kcron/parsers/DaysOfWeekPartTests.kt | 10 +++++++- .../com/ucasoft/kcron/parsers/ParserTests.kt | 2 ++ 13 files changed, 73 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index d39655a..c14193e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # KCron Common Cron realization for Kotlin Multiplatform -[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Scogun_kcron-common&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Scogun_kcron-common) ![GitHub](https://img.shields.io/github/license/Scogun/kcron-common?color=blue) ![Publish workflow](https://github.com/Scogun/kcron-common/actions/workflows/publish.yml/badge.svg) [![Maven Central with version prefix filter](https://img.shields.io/maven-central/v/com.ucasoft.kcron/kcron-common/0.3.1?color=blue)](https://search.maven.org/artifact/com.ucasoft.kcron/kcron-common/0.3.1/jar) +[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Scogun_kcron-common&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=Scogun_kcron-common) ![GitHub](https://img.shields.io/github/license/Scogun/kcron-common?color=blue) ![Publish workflow](https://github.com/Scogun/kcron-common/actions/workflows/publish.yml/badge.svg) [![Maven Central with version prefix filter](https://img.shields.io/maven-central/v/com.ucasoft.kcron/kcron-common/0.5.0?color=blue)](https://search.maven.org/artifact/com.ucasoft.kcron/kcron-common/0.5.0/jar) ### Features * Kotlin Multiplatform library @@ -31,7 +31,7 @@ kotlin { sourceSets { commonMain { dependencies { - implementation 'com.ucasoft.kcron:kcron-common:0.3.1' + implementation 'com.ucasoft.kcron:kcron-common:0.5.0' } } } @@ -79,11 +79,11 @@ println(builder.nextRun) // 2050-02-07T05:05:15 ``` ***Easy change any part of expression*** ```kotlin -val builder = KCron.parseAndBuild("0/10 5-25 5,12 ? * 7#5 2050") +val builder = KCron.parseAndBuild("0/10 5-25 5,12 ? * SUN#5 2050") builder.years(2021..2025) -println(builder.expression) // 0/10 5-25 5,12 ? * 7#5 2021-2025 +println(builder.expression) // 0/10 5-25 5,12 ? * SUN#5 2021-2025 ``` ### Current status -This library is on alpha version `0.3.1`. +This library is on beta version `0.5.0`. However, it will be a part of another cool library. Check the news! diff --git a/build.gradle b/build.gradle index 600ac1d..cbd3987 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'com.ucasoft.kcron' -version = '0.3.1' +version = '0.5.0' repositories { mavenCentral() diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt index ed70e81..e920275 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt @@ -9,8 +9,8 @@ class DaysOfWeekBuilder(private val firstWeekDay: WeekDays = WeekDays.Monday) : private val dayWeekNames = WeekDays.values().map { v -> v.shortName } - override fun build(type: DayOfWeekGroups, value: String) - { + override fun build(type: DayOfWeekGroups, value: String) { + val firstWeekDayIndex = WeekDays.values().indexOf(firstWeekDay) when (type) { DayOfWeekGroups.Any -> { daysOfWeek = listOf(1..7).flatten() @@ -18,21 +18,33 @@ class DaysOfWeekBuilder(private val firstWeekDay: WeekDays = WeekDays.Monday) : DayOfWeekGroups.Specific -> { val data = value.split(',') daysOfWeek = if (data.all { d -> dayWeekNames.contains(d) }) { - val firstWeekDayIndex = WeekDays.values().indexOf(firstWeekDay) data.map { d -> dayShift(firstWeekDayIndex, dayWeekNames.indexOf(d)) }.sorted() } else { data.map { d -> d.toInt() }.sorted() } } DayOfWeekGroups.EveryStartingAt -> { - val data = value.split('/').map { v -> v.toInt() } - daysOfWeek = listOf(data[0]..7 step data[1]).flatten() + val data = value.split('/') + daysOfWeek = listOf( + if (dayWeekNames.contains(data[0])) { + dayShift(firstWeekDayIndex, dayWeekNames.indexOf(data[0])) + } else { + data[0].toInt() + }..7 step data[1].toInt() + ).flatten() } DayOfWeekGroups.Last -> { daysOfWeek = listOf(value.removeSuffix("L").toInt() * -1) } DayOfWeekGroups.OfMonth -> { - daysOfWeek = value.split('#').map { v -> v.toInt() * 10 } + val data = value.split('#') + daysOfWeek = listOf( + if (dayWeekNames.contains(data[0])) { + dayShift(firstWeekDayIndex, dayWeekNames.indexOf(data[0])) + } else { + data[0].toInt() + } * 10, data[1].toInt() * 10 + ) } } } diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt index 1e97e82..e7c4bd9 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt @@ -1,8 +1,13 @@ package com.ucasoft.kcron.extensions -class At(private val every: Int, private val starting: Int) { +import com.ucasoft.kcron.common.WeekDays + +class At(private val every: Int, private val starting: String) { + constructor(every: Int, starting: WeekDays) : this(every, starting.shortName) override fun toString() = "$starting/$every" } -infix fun Int.at(starting: Int) : At = At(this, starting) \ No newline at end of file +infix fun Int.at(starting: Int) : At = At(this, starting.toString()) + +infix fun Int.at(starting: WeekDays) : At = At(this, starting) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt index ad61000..0ab50f6 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt @@ -1,8 +1,13 @@ package com.ucasoft.kcron.extensions -class On(private val dayOfWeek: Int, private val index: Int) { +import com.ucasoft.kcron.common.WeekDays + +class On(private val dayOfWeek: String, private val index: Int) { + constructor(dayOfWeek: WeekDays, index: Int) : this(dayOfWeek.shortName, index) override fun toString() = "$dayOfWeek#$index" } -infix fun Int.on(index: Int) : On = On(this, index) \ No newline at end of file +infix fun Int.on(index: Int) : On = On(this.toString(), index) + +infix fun WeekDays.on(index: Int) : On = On(this, index) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt index acac6db..0151de2 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt @@ -6,9 +6,16 @@ abstract class AnySpecificEveryAtParser( anyPattern: String, specificNumberPattern: String, specificNamePattern: String = "", - secondLimitPattern: String = "") + private val secondLimitPattern: String = "") : AnySpecificParser(anyPattern, specificNumberPattern, specificNamePattern) where T: Enum, T: CronGroups { - override val additionalParts: String = "|((?:${specificNumberPattern})/(?:${secondLimitPattern.ifEmpty { specificNumberPattern }}))" + override val additionalParts: String + get() { + if (specificNamePattern.isNotEmpty()) { + return "|((?:(?:${specificNumberPattern})|(?:${specificNamePattern}))/(?:${secondLimitPattern.ifEmpty { specificNumberPattern }}))" + } + + return "|((?:${specificNumberPattern})/(?:${secondLimitPattern.ifEmpty { specificNumberPattern }}))" + } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt index 3f9159e..d191276 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt @@ -5,7 +5,7 @@ import com.ucasoft.kcron.common.CronGroups abstract class AnySpecificEveryParser( anyPattern: String, specificNumberPattern: String, - private val specificNamePattern: String = "", + specificNamePattern: String = "", secondNumberPattern: String = "") : AnySpecificEveryAtParser(anyPattern, specificNumberPattern, specificNamePattern, secondNumberPattern) where T: Enum, T: CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt index f189a6f..3fd8c23 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt @@ -5,7 +5,7 @@ import com.ucasoft.kcron.common.CronGroups abstract class AnySpecificParser( private val anyPattern: String, protected val specificNumberPattern: String, - private val specificNamePattern: String = "") : BaseParser() where T: Enum, T: CronGroups { + protected val specificNamePattern: String = "") : BaseParser() where T: Enum, T: CronGroups { abstract val additionalParts: String diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt index 801b858..301b6a1 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt @@ -6,7 +6,7 @@ import com.ucasoft.kcron.common.DayOfWeekGroups class DaysOfWeekParser : AnySpecificEveryAtParser("[*?]", "[1-7]", listOf("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT").joinToString("|")) { override val additionalParts: String - get() = super.additionalParts + "|((?:$specificNumberPattern)L)|((?:$specificNumberPattern)#[1-5])" + get() = super.additionalParts + "|((?:$specificNumberPattern)L)|((?:(?:$specificNumberPattern)|(?:$specificNamePattern))#[1-5])" override val unknownGroup = DayOfWeekGroups.Unknown diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt index 6dabb0b..fa667da 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt @@ -60,8 +60,8 @@ class BuilderTests { result = builder.nextRunList(2) assertEquals(expected.plusDays(2), result[0]) assertEquals(expected.plusDays(3), result[1]) - builder.daysOfWeek(3 at 6) - assertEquals("0 0 0 ? 1 6/3 2099", builder.expression) + builder.daysOfWeek(3 at WeekDays.Saturday) + assertEquals("0 0 0 ? 1 SAT/3 2099", builder.expression) result = builder.nextRunList(2) assertEquals(expected.plusDays(2), result[0]) assertEquals(expected.plusDays(9), result[1]) @@ -87,12 +87,12 @@ class BuilderTests { result = builder.nextRunList(2) assertEquals(expected.plusDays(1), result[0]) assertEquals(expected.plusDays(2), result[1]) - builder.daysOfWeek(3 at 6) + builder.daysOfWeek(3 at WeekDays.Friday) result = builder.nextRunList(2) assertEquals(expected.plusDays(1), result[0]) assertEquals(expected.plusDays(8), result[1]) - builder.daysOfWeek(7 on 5) - assertEquals("0 0 0 ? 1 7#5 2099", builder.expression) + builder.daysOfWeek(WeekDays.Saturday on 5) + assertEquals("0 0 0 ? 1 SAT#5 2099", builder.expression) assertEquals(expected.plusDays(30), builder.nextRun) } @@ -113,12 +113,12 @@ class BuilderTests { result = builder.nextRunList(2) assertEquals(expected.plusDays(4), result[0]) assertEquals(expected.plusDays(5), result[1]) - builder.daysOfWeek(3 at 6) + builder.daysOfWeek(3 at WeekDays.Monday) result = builder.nextRunList(2) assertEquals(expected.plusDays(4), result[0]) assertEquals(expected.plusDays(11), result[1]) - builder.daysOfWeek(2 on 5) - assertEquals("0 0 0 ? 1 2#5 2099", builder.expression) + builder.daysOfWeek(WeekDays.Thursday on 5) + assertEquals("0 0 0 ? 1 THU#5 2099", builder.expression) assertEquals(expected.plusDays(28), builder.nextRun) } } diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt index 17601eb..a829191 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt @@ -20,10 +20,14 @@ class DaysOfWeekBuilderTests { assertEquals(listOf(1, 3, 5, 7), builder.daysOfWeek) builder.build(DayOfWeekGroups.EveryStartingAt, "2/2") assertEquals(listOf(2, 4, 6), builder.daysOfWeek) + builder.build(DayOfWeekGroups.EveryStartingAt, "MON/3") + assertEquals(listOf(1, 4, 7), builder.daysOfWeek) builder.build(DayOfWeekGroups.Last, "2L") assertEquals(listOf(-2), builder.daysOfWeek) builder.build(DayOfWeekGroups.OfMonth, "1#5") assertEquals(listOf(10, 50), builder.daysOfWeek) + builder.build(DayOfWeekGroups.OfMonth, "SAT#5") + assertEquals(listOf(60, 50), builder.daysOfWeek) } @Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt index 5829512..a3033fb 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt @@ -16,13 +16,17 @@ class DaysOfWeekPartTests { DayOfWeekValueGroup("1,7", DayOfWeekGroups.Specific), DayOfWeekValueGroup("1,3,5,7", DayOfWeekGroups.Specific), DayOfWeekValueGroup("1/1", DayOfWeekGroups.EveryStartingAt), + DayOfWeekValueGroup("MON/1", DayOfWeekGroups.EveryStartingAt), DayOfWeekValueGroup("1/7", DayOfWeekGroups.EveryStartingAt), DayOfWeekValueGroup("7/7", DayOfWeekGroups.EveryStartingAt), + DayOfWeekValueGroup("SUN/7", DayOfWeekGroups.EveryStartingAt), DayOfWeekValueGroup("7/1", DayOfWeekGroups.EveryStartingAt), DayOfWeekValueGroup("1L", DayOfWeekGroups.Last), DayOfWeekValueGroup("7L", DayOfWeekGroups.Last), DayOfWeekValueGroup("7#1", DayOfWeekGroups.OfMonth), + DayOfWeekValueGroup("SUN#1", DayOfWeekGroups.OfMonth), DayOfWeekValueGroup("1#5", DayOfWeekGroups.OfMonth), + DayOfWeekValueGroup("MON#5", DayOfWeekGroups.OfMonth), DayOfWeekValueGroup("6#2", DayOfWeekGroups.OfMonth) ) @@ -37,14 +41,18 @@ class DaysOfWeekPartTests { "0,7", "1,3,5,8", "1/", + "TUE/", "1/8", + "1/SUN", "/7", "8/2", "0L", "8L", "6M", "8#1", - "6#6" + "6#6", + "2#TUE", + "FRI#6" ) @BeforeTest diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt index 7a44200..6a078c5 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt @@ -16,6 +16,7 @@ class ParserTests { parser.parse("* * * ? * * *") parser.parse("* * * 29 * ? *") parser.parse("* * * ? * 1L *") + parser.parse("* * * ? * MON/1 *") } @Test @@ -27,6 +28,7 @@ class ParserTests { @Test fun badExpressionParts() { assertFailsWith{ parser.parse("62 * * ? * * *") } + assertFailsWith { parser.parse("* * * ? * MON#6 *") } assertFailsWith { parser.parse("62 * 25 ? * * *") } }