From 27fa78cc30fc31fe71d013ad12925b096a4cfb03 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 10 Jan 2024 21:29:53 +0100 Subject: [PATCH 1/6] Start working --- .../kotlin/com/ucasoft/kcron/Cron.kt | 10 ++- .../com/ucasoft/kcron/builders/Builder.kt | 64 +++++++------- .../ucasoft/kcron/builders/CronDateTime.kt | 87 +++++++++++++++++++ .../com/ucasoft/kcron/extensions/Builder.kt | 63 +++++++------- .../ucasoft/kcron/builders/BuilderTests.kt | 30 +++---- 5 files changed, 171 insertions(+), 83 deletions(-) create mode 100644 src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt b/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt index d6a3986..955878b 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt @@ -1,23 +1,25 @@ package com.ucasoft.kcron import com.ucasoft.kcron.builders.Builder +import com.ucasoft.kcron.builders.CronLocalDateTime import com.ucasoft.kcron.common.WeekDays import com.ucasoft.kcron.parsers.Parser import com.ucasoft.kcron.settings.Settings +import kotlinx.datetime.LocalDateTime class Cron { companion object { - fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) : Builder { + fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) : Builder { val settings = Settings() block.invoke(settings) val parseResult = Parser().parse(expression, settings.version) - return Builder(settings.firstDayOfWeek).build(parseResult.parts) + return Builder(settings.firstDayOfWeek, CronLocalDateTime()).build(parseResult.parts) } - fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday): Builder { - return Builder(firstDayOfWeek) + fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday): Builder { + return Builder(firstDayOfWeek, CronLocalDateTime()) } } } diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt index eefcdf7..1c419dc 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt @@ -1,10 +1,8 @@ package com.ucasoft.kcron.builders import com.ucasoft.kcron.common.* -import com.ucasoft.kcron.extensions.* -import kotlinx.datetime.* -class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { +class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, private val dateTimeInstance: C) { private val partBuilders = mapOf( CronPart.Seconds to SecondsBuilder(), @@ -27,7 +25,7 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { } @OptIn(DelicateIterableApi::class) - val nextRun : LocalDateTime? + val nextRun : T? get() = asIterable().firstOrNull() val expression: String @@ -35,27 +33,27 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { private val firstDayOfWeekIndex = WeekDays.entries.indexOf(firstDayOfWeek) - fun build(parts: Map): Builder { + fun build(parts: Map): Builder { parts.forEach { entry -> partBuilders[entry.key]?.commonBuild(entry.value.type, entry.value.value) } return this } - fun seconds(type: TimeGroups, value: String) : Builder { + fun seconds(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Seconds).commonBuild(type, value) return this } - fun minutes(type: TimeGroups, value: String) : Builder { + fun minutes(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Minutes).commonBuild(type, value) return this } - fun hours(type: TimeGroups, value: String) : Builder { + fun hours(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Hours).commonBuild(type, value) return this } - fun days(type: DayGroups, value: String) : Builder { + fun days(type: DayGroups, value: String) : Builder { if (type != DayGroups.Any) { daysOfWeek(DayOfWeekGroups.Any, "?") } else if (partBuilders.getValue(CronPart.DaysOfWeek).value == "?") { @@ -65,12 +63,12 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { return this } - fun months(type: MonthGroups, value: String) : Builder { + fun months(type: MonthGroups, value: String) : Builder { partBuilders.getValue(CronPart.Months).commonBuild(type, value) return this } - fun daysOfWeek(type: DayOfWeekGroups, value: String) : Builder { + fun daysOfWeek(type: DayOfWeekGroups, value: String) : Builder { if (type != DayOfWeekGroups.Any) { days(DayGroups.Any, "?") } @@ -78,13 +76,13 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { return this } - fun years(type: YearGroups, value: String) : Builder { + fun years(type: YearGroups, value: String) : Builder { partBuilders.getValue(CronPart.Years).commonBuild(type, value) return this } @DelicateIterableApi - fun asIterable(start: LocalDateTime): Iterable { + fun asIterable(start: C): Iterable { return Iterable { iterator { for (year in (partBuilders.getValue(CronPart.Years) as YearsBuilder).years.filter { y -> y >= start.year }) { @@ -93,7 +91,7 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { for (hour in (partBuilders.getValue(CronPart.Hours) as HoursBuilder).hours.filter { h -> h >= start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { for (minute in (partBuilders.getValue(CronPart.Minutes) as MinutesBuilder).minutes.filter { m -> m >= start.minute || hour > start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { for (seconds in (partBuilders.getValue(CronPart.Seconds) as SecondsBuilder).seconds.filter { s -> s > start.second || minute > start.minute || hour > start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { - yield(LocalDateTime(year, month, day, hour, minute, seconds)) + yield(dateTimeInstance.from(year, month, day, hour, minute, seconds).cast()) } } } @@ -105,9 +103,9 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { } @DelicateIterableApi - fun asIterable(): Iterable { - val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) - return asIterable(start = now) + fun asIterable(): Iterable { + //val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) + return asIterable(dateTimeInstance.now() as C) } @Deprecated( @@ -120,11 +118,11 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { ), ) @OptIn(DelicateIterableApi::class) - fun nextRunList(maxCount: Int = 10) : List { + fun nextRunList(maxCount: Int = 10) : List { return asIterable().take(maxCount) } - private fun calculateDays(year: Int, month: Int, daysOfWeek: List, days: List, now: LocalDateTime): List { + private fun calculateDays(year: Int, month: Int, daysOfWeek: List, days: List, now: CronDateTime): List { var lastDay = lastMonthDay(year, month) val lastDayInt = lastDay.dayOfMonth if (daysOfWeek.isNotEmpty() && daysOfWeek.size < 7) { @@ -136,8 +134,8 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { firstValue == -32 -> return listOf(lastDayInt) firstValue < 0 -> return listOf(lastDay.minusDays(firstValue).dayOfMonth) firstValue == 32 -> { - if (lastDay.dayOfWeek.isoDayNumber >= 6) { - lastDay = lastDay.minusDays(lastDay.dayOfWeek.isoDayNumber - 5) + if (lastDay.isoDayOfWeek >= 6) { + lastDay = lastDay.minusDays(lastDay.isoDayOfWeek - 5) } return listOf(lastDay.dayOfMonth) } @@ -156,21 +154,21 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { private fun calculateDaysBasedOnDaysOfWeek( year: Int, month: Int, - lastMonthDay: LocalDateTime, + lastMonthDay: CronDateTime, daysOfWeek: List, - now: LocalDateTime + now: CronDateTime ): List { val firstValue = daysOfWeek[0] if (firstValue < 0) { val lastOf = toIsoDayOfWeek(firstValue * -1) - var difference = lastMonthDay.dayOfWeek.isoDayNumber - lastOf + var difference = lastMonthDay.isoDayOfWeek - lastOf if (difference < 0) { difference += 7 } return listOf(lastMonthDay.minusDays(difference).dayOfMonth) } val lastDayInt = lastMonthDay.dayOfMonth - val firstInMonth = LocalDateTime(year, month, 1, 0, 0) + val firstInMonth = dateTimeInstance.from(year, month, 1) val startDay = if (now.monthNumber == month && now.year == year) { now } else { firstInMonth } if (firstValue >= 10) { val dayOfWeek = toIsoDayOfWeek(firstValue / 10) @@ -196,8 +194,8 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { return result } - private fun dayOfWeekByIndex(dayOfWeek: Int, index: Int, startDay: LocalDateTime, lastDayInt: Int): Int? { - var difference = dayOfWeek - startDay.dayOfWeek.isoDayNumber + private fun dayOfWeekByIndex(dayOfWeek: Int, index: Int, startDay: CronDateTime, lastDayInt: Int): Int? { + var difference = dayOfWeek - startDay.isoDayOfWeek if (difference < 0) { difference += 7 } @@ -209,9 +207,9 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { } private fun nearestWorkDayTo(year: Int, month: Int, lastMonthDay: Int, day: Int) : Int { - var checkingDay = LocalDateTime(year, month, day, 0, 0) - if (checkingDay.dayOfWeek.isoDayNumber >= 6) { - checkingDay = if (checkingDay.dayOfWeek.isoDayNumber == 6) { + var checkingDay = dateTimeInstance.from(year, month, day) + if (checkingDay.isoDayOfWeek >= 6) { + checkingDay = if (checkingDay.isoDayOfWeek == 6) { if (checkingDay.dayOfMonth > 1) { checkingDay.minusDays(1) } else { @@ -234,14 +232,14 @@ class Builder(firstDayOfWeek: WeekDays = WeekDays.Monday) { return index } - private fun lastMonthDay(year: Int, month: Int): LocalDateTime { + private fun lastMonthDay(year: Int, month: Int): CronDateTime { var nextMonth = month + 1 var nextYear = year if (nextMonth > 12) { nextYear += 1 nextMonth = 1 } - val firstDayNextMonth = LocalDateTime(nextYear, nextMonth, 1, 0, 0).toInstant(TimeZone.currentSystemDefault()) - return firstDayNextMonth.plus(-1, DateTimeUnit.DAY, TimeZone.currentSystemDefault()).toLocalDateTime(TimeZone.currentSystemDefault()) + val firstDayNextMonth = dateTimeInstance.from(nextYear, nextMonth, 1) + return firstDayNextMonth.minusDays(1) } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt new file mode 100644 index 0000000..bd89e0c --- /dev/null +++ b/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt @@ -0,0 +1,87 @@ +package com.ucasoft.kcron.builders + +import com.ucasoft.kcron.extensions.minusDays +import com.ucasoft.kcron.extensions.plusDays +import kotlinx.datetime.* + +interface CronDateTime { + + val year: Int + + val monthNumber: Int + + val dayOfMonth: Int + + val isoDayOfWeek: Int + + val hour: Int + + val minute: Int + + val second: Int + + fun now() : CronDateTime + + fun cast() : T + + fun from(year: Int, month: Int, day: Int, hours: Int = 0, minutes: Int = 0, seconds: Int = 0): CronDateTime + + fun plusDays(days: Int): CronDateTime + + fun minusDays(days: Int): CronDateTime +} + +class CronLocalDateTime: CronDateTime { + + + private val dateTime: LocalDateTime + + constructor() { + dateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) + } + + constructor(year: Int, + month: Int, + day: Int, + hour: Int, + minute: Int, + second: Int) { + dateTime = LocalDateTime(year, month, day, hour, minute, second) + } + + override val year: Int + get() = dateTime.year + + override val monthNumber: Int + get() = dateTime.monthNumber + + override val dayOfMonth: Int + get() = dateTime.dayOfMonth + override val isoDayOfWeek: Int + get() = dateTime.dayOfWeek.isoDayNumber + override val hour: Int + get() = dateTime.hour + override val minute: Int + get() = dateTime.minute + override val second: Int + get() = dateTime.second + + override fun now() = CronLocalDateTime() + + override fun cast() = dateTime + + override fun from( + year: Int, + month: Int, + day: Int, + hours: Int, + minutes: Int, + seconds: Int + ) = CronLocalDateTime(year, month, day, hours, minutes, seconds) + + override fun plusDays(days: Int) = dateTime.plusDays(days).toCronLocalDateTime() + + override fun minusDays(days: Int) = dateTime.minusDays(days).toCronLocalDateTime() +} + +fun LocalDateTime.toCronLocalDateTime() = CronLocalDateTime(this.year, this.monthNumber, this.dayOfMonth, this.hour, this.minute, this.second) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt index a87a164..33a564d 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt @@ -1,128 +1,129 @@ package com.ucasoft.kcron.extensions import com.ucasoft.kcron.builders.Builder +import com.ucasoft.kcron.builders.CronDateTime import com.ucasoft.kcron.common.* -fun Builder.anySeconds() : Builder { +fun > Builder.anySeconds() : Builder { return seconds(TimeGroups.Any, "*") } -fun Builder.seconds(vararg values: Int) : Builder { +fun > Builder.seconds(vararg values: Int) : Builder { return seconds(TimeGroups.Specific, values.joinToString(",")) } -fun Builder.seconds(at: At) : Builder { +fun > Builder.seconds(at: At) : Builder { return seconds(TimeGroups.EveryStartingAt, at.toString()) } -fun Builder.seconds(between: IntRange) : Builder { +fun > Builder.seconds(between: IntRange) : Builder { return seconds(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun Builder.anyMinutes() : Builder { +fun > Builder.anyMinutes() : Builder { return minutes(TimeGroups.Any, "*") } -fun Builder.minutes(vararg values: Int) : Builder { +fun > Builder.minutes(vararg values: Int) : Builder { return minutes(TimeGroups.Specific, values.joinToString(",")) } -fun Builder.minutes(at: At) : Builder { +fun > Builder.minutes(at: At) : Builder { return minutes(TimeGroups.EveryStartingAt, at.toString()) } -fun Builder.minutes(between: IntRange) : Builder { +fun > Builder.minutes(between: IntRange) : Builder { return minutes(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun Builder.anyHours() : Builder { +fun > Builder.anyHours() : Builder { return hours(TimeGroups.Any, "*") } -fun Builder.hours(vararg values: Int) : Builder { +fun > Builder.hours(vararg values: Int) : Builder { return hours(TimeGroups.Specific, values.joinToString(",")) } -fun Builder.hours(at: At) : Builder { +fun > Builder.hours(at: At) : Builder { return hours(TimeGroups.EveryStartingAt, at.toString()) } -fun Builder.hours(between: IntRange) : Builder { +fun > Builder.hours(between: IntRange) : Builder { return hours(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun Builder.anyDays() : Builder { +fun > Builder.anyDays() : Builder { return days(DayGroups.Any, "?") } -fun Builder.days(vararg values: Int) : Builder { +fun > Builder.days(vararg values: Int) : Builder { return days(DayGroups.Specific, values.joinToString(",")) } -fun Builder.days(at: At) : Builder { +fun > Builder.days(at: At) : Builder { return days(DayGroups.EveryStartingAt, at.toString()) } -fun Builder.lastDay() : Builder { +fun > Builder.lastDay() : Builder { return days(DayGroups.LastDay, "L") } -fun Builder.lastWorkDay() : Builder { +fun > Builder.lastWorkDay() : Builder { return days(DayGroups.LastWeekday, "LW") } -fun Builder.nearestWorkDay(value: Int) : Builder { +fun > Builder.nearestWorkDay(value: Int) : Builder { return days(DayGroups.NearestWeekday, "${value}W") } -fun Builder.anyMonths() : Builder { +fun > Builder.anyMonths() : Builder { return months(MonthGroups.Any, "*") } -fun Builder.months(vararg values: Int) : Builder { +fun > Builder.months(vararg values: Int) : Builder { return months(MonthGroups.Specific, values.joinToString(",")) } -fun Builder.months(at: At) : Builder { +fun > Builder.months(at: At) : Builder { return months(MonthGroups.EveryStartingAt, at.toString()) } -fun Builder.months(between: IntRange) : Builder { +fun > Builder.months(between: IntRange) : Builder { return months(MonthGroups.EveryBetween, "${between.first}-${between.last}") } -fun Builder.anyDaysOfWeek(any: String = "*") : Builder { +fun > Builder.anyDaysOfWeek(any: String = "*") : Builder { return daysOfWeek(DayOfWeekGroups.Any, any) } -fun Builder.daysOfWeek(vararg values: Int) : Builder { +fun > Builder.daysOfWeek(vararg values: Int) : Builder { return daysOfWeek(DayOfWeekGroups.Specific, values.joinToString(",") ) } -fun Builder.daysOfWeek(at: At) : Builder { +fun > Builder.daysOfWeek(at: At) : Builder { return daysOfWeek(DayOfWeekGroups.EveryStartingAt, at.toString()) } -fun Builder.lastDayOfWeek(value: Int) : Builder { +fun > Builder.lastDayOfWeek(value: Int) : Builder { return daysOfWeek(DayOfWeekGroups.Last, "${value}L") } -fun Builder.daysOfWeek(on: On) : Builder { +fun > Builder.daysOfWeek(on: On) : Builder { return daysOfWeek(DayOfWeekGroups.OfMonth, on.toString()) } -fun Builder.anyYears() : Builder { +fun > Builder.anyYears() : Builder { return years(YearGroups.Any, "*") } -fun Builder.years(vararg values: Int): Builder { +fun > Builder.years(vararg values: Int): Builder { return years(YearGroups.Specific, values.joinToString(",")) } -fun Builder.years(at: At) : Builder { +fun > Builder.years(at: At) : Builder { return years(YearGroups.EveryStartingAt, at.toString()) } -fun Builder.years(between: IntRange) : Builder { +fun > Builder.years(between: IntRange) : Builder { return years(YearGroups.EveryBetween, "${between.first}-${between.last}") } \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt index fab3aa0..fdacc49 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt @@ -18,7 +18,7 @@ class BuilderTests { @Test fun buildMany() { - val builder = Builder() + val builder = Builder(dateTimeInstance = CronLocalDateTime()) builder.expression.shouldBe("* * * ? * * *") builder.days(1) builder.expression.shouldBe("* * * 1 * ? *") @@ -81,7 +81,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsSunday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Sunday) + val builder = Builder(WeekDays.Sunday, CronLocalDateTime()) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -109,7 +109,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsWednesday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Wednesday) + val builder = Builder(WeekDays.Wednesday, CronLocalDateTime()) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -137,51 +137,51 @@ class BuilderTests { @Test fun iterableShouldStartFromStartDateTimeWhenItInSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder().years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2060 00:00:00 val start = LocalDate(2060, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2060 12:00:00 val expected = LocalDate(2060, 1, 1).atTime(12, 0, 0) - val actual = builder.asIterable(start).first() - actual.shouldBeEqual(expected) + /*val actual = builder.asIterable(start).first() + actual.shouldBeEqual(expected)*/ } @Test fun iterableShouldStartFromFirstDatetimeDefinedByCronWhenStartDateTimeIsBeforeSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder().years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2010 00:00:00 val start = LocalDate(2010, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2050 12:00:00 (as defined in cron) val expected = LocalDate(2050, 1, 1).atTime(12, 0, 0) - val actual = builder.asIterable(start).first() - actual.shouldBeEqual(expected) + /*val actual = builder.asIterable(start).first() + actual.shouldBeEqual(expected)*/ } @Test fun iterableShouldBeEmptyWhenStartDateTimeIsAfterSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder().years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2080 00:00:00 val start = LocalDate(2080, 1, 1).atTime(0, 0, 0) - val actual = builder.asIterable(start).take(2) + /*val actual = builder.asIterable(start).take(2) // expect actual value to be empty because 2080 is out of 2050..2070 range - actual.shouldBeEmpty() + actual.shouldBeEmpty()*/ } @Test fun iterableShouldBeFiniteForCronWithSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder().years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2070 00:00:00 val start = LocalDate(2070, 1, 1).atTime(0, 0, 0) // set expected runs count to be exactly 365 (once per day) val expected = 365 - val actual = builder.asIterable(start).toList() - actual.shouldHaveSize(expected) + /* val actual = builder.asIterable(start).toList() + actual.shouldHaveSize(expected)*/ } } From c1a9bb15ec440a908fbe1fbb08dd444a51ff3e01 Mon Sep 17 00:00:00 2001 From: Sergey Antonov Date: Thu, 11 Jan 2024 09:21:27 +0100 Subject: [PATCH 2/6] Fix via provider --- .../kotlin/com/ucasoft/kcron/Cron.kt | 10 +-- .../com/ucasoft/kcron/builders/Builder.kt | 59 +++++++++-------- .../ucasoft/kcron/builders/CronDateTime.kt | 40 ++++++++---- .../com/ucasoft/kcron/extensions/Builder.kt | 63 ++++++++++--------- .../ucasoft/kcron/builders/BuilderTests.kt | 30 ++++----- 5 files changed, 111 insertions(+), 91 deletions(-) diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt b/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt index 955878b..6428ce6 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt @@ -1,7 +1,9 @@ package com.ucasoft.kcron import com.ucasoft.kcron.builders.Builder +import com.ucasoft.kcron.builders.CronDateTimeProvider import com.ucasoft.kcron.builders.CronLocalDateTime +import com.ucasoft.kcron.builders.CronLocalDateTimeProvider import com.ucasoft.kcron.common.WeekDays import com.ucasoft.kcron.parsers.Parser import com.ucasoft.kcron.settings.Settings @@ -11,15 +13,15 @@ class Cron { companion object { - fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) : Builder { + fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) : Builder { val settings = Settings() block.invoke(settings) val parseResult = Parser().parse(expression, settings.version) - return Builder(settings.firstDayOfWeek, CronLocalDateTime()).build(parseResult.parts) + return Builder(settings.firstDayOfWeek, CronLocalDateTimeProvider()).build(parseResult.parts) } - fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday): Builder { - return Builder(firstDayOfWeek, CronLocalDateTime()) + fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday): Builder { + return Builder(firstDayOfWeek, CronLocalDateTimeProvider()) } } } diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt index 1c419dc..e185f7c 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt @@ -2,7 +2,7 @@ package com.ucasoft.kcron.builders import com.ucasoft.kcron.common.* -class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, private val dateTimeInstance: C) { +class Builder, P: CronDateTimeProvider>(firstDayOfWeek: WeekDays = WeekDays.Monday, private val dateTimeProvider: P) { private val partBuilders = mapOf( CronPart.Seconds to SecondsBuilder(), @@ -33,27 +33,27 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, private val firstDayOfWeekIndex = WeekDays.entries.indexOf(firstDayOfWeek) - fun build(parts: Map): Builder { + fun build(parts: Map): Builder { parts.forEach { entry -> partBuilders[entry.key]?.commonBuild(entry.value.type, entry.value.value) } return this } - fun seconds(type: TimeGroups, value: String) : Builder { + fun seconds(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Seconds).commonBuild(type, value) return this } - fun minutes(type: TimeGroups, value: String) : Builder { + fun minutes(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Minutes).commonBuild(type, value) return this } - fun hours(type: TimeGroups, value: String) : Builder { + fun hours(type: TimeGroups, value: String) : Builder { partBuilders.getValue(CronPart.Hours).commonBuild(type, value) return this } - fun days(type: DayGroups, value: String) : Builder { + fun days(type: DayGroups, value: String) : Builder { if (type != DayGroups.Any) { daysOfWeek(DayOfWeekGroups.Any, "?") } else if (partBuilders.getValue(CronPart.DaysOfWeek).value == "?") { @@ -63,12 +63,12 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, return this } - fun months(type: MonthGroups, value: String) : Builder { + fun months(type: MonthGroups, value: String) : Builder { partBuilders.getValue(CronPart.Months).commonBuild(type, value) return this } - fun daysOfWeek(type: DayOfWeekGroups, value: String) : Builder { + fun daysOfWeek(type: DayOfWeekGroups, value: String) : Builder { if (type != DayOfWeekGroups.Any) { days(DayGroups.Any, "?") } @@ -76,22 +76,23 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, return this } - fun years(type: YearGroups, value: String) : Builder { + fun years(type: YearGroups, value: String) : Builder { partBuilders.getValue(CronPart.Years).commonBuild(type, value) return this } @DelicateIterableApi - fun asIterable(start: C): Iterable { + fun asIterable(start: T): Iterable { + val internalStart = dateTimeProvider.from(start) return Iterable { iterator { - for (year in (partBuilders.getValue(CronPart.Years) as YearsBuilder).years.filter { y -> y >= start.year }) { - for (month in (partBuilders.getValue(CronPart.Months) as MonthsBuilder).months.filter { m -> m >= start.monthNumber || year > start.year}) { - for (day in calculateDays(year, month, (partBuilders.getValue(CronPart.DaysOfWeek) as DaysOfWeekBuilder).daysOfWeek, (partBuilders.getValue(CronPart.Days) as DaysBuilder).days, start)) { - for (hour in (partBuilders.getValue(CronPart.Hours) as HoursBuilder).hours.filter { h -> h >= start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { - for (minute in (partBuilders.getValue(CronPart.Minutes) as MinutesBuilder).minutes.filter { m -> m >= start.minute || hour > start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { - for (seconds in (partBuilders.getValue(CronPart.Seconds) as SecondsBuilder).seconds.filter { s -> s > start.second || minute > start.minute || hour > start.hour || day > start.dayOfMonth || month > start.monthNumber || year > start.year }) { - yield(dateTimeInstance.from(year, month, day, hour, minute, seconds).cast()) + for (year in (partBuilders.getValue(CronPart.Years) as YearsBuilder).years.filter { y -> y >= internalStart.year }) { + for (month in (partBuilders.getValue(CronPart.Months) as MonthsBuilder).months.filter { m -> m >= internalStart.month || year > internalStart.year}) { + for (day in calculateDays(year, month, (partBuilders.getValue(CronPart.DaysOfWeek) as DaysOfWeekBuilder).daysOfWeek, (partBuilders.getValue(CronPart.Days) as DaysBuilder).days, internalStart)) { + for (hour in (partBuilders.getValue(CronPart.Hours) as HoursBuilder).hours.filter { h -> h >= internalStart.hour || day > internalStart.dayOfMonth || month > internalStart.month || year > internalStart.year }) { + for (minute in (partBuilders.getValue(CronPart.Minutes) as MinutesBuilder).minutes.filter { m -> m >= internalStart.minute || hour > internalStart.hour || day > internalStart.dayOfMonth || month > internalStart.month || year > internalStart.year }) { + for (seconds in (partBuilders.getValue(CronPart.Seconds) as SecondsBuilder).seconds.filter { s -> s > internalStart.second || minute > internalStart.minute || hour > internalStart.hour || day > internalStart.dayOfMonth || month > internalStart.month || year > internalStart.year }) { + yield(dateTimeProvider.from(year, month, day, hour, minute, seconds).cast()) } } } @@ -103,10 +104,7 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, } @DelicateIterableApi - fun asIterable(): Iterable { - //val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) - return asIterable(dateTimeInstance.now() as C) - } + fun asIterable() = asIterable(dateTimeProvider.now().cast()) @Deprecated( message = "Use asIterable().take(maxCount) instead.", @@ -148,7 +146,7 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, } } } - return days.filter { d -> (d >= now.dayOfMonth || month > now.monthNumber || year > now.year) && (d <= lastDayInt) } + return days.filter { d -> (d >= now.dayOfMonth || month > now.month || year > now.year) && (d <= lastDayInt) } } private fun calculateDaysBasedOnDaysOfWeek( @@ -168,8 +166,8 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, return listOf(lastMonthDay.minusDays(difference).dayOfMonth) } val lastDayInt = lastMonthDay.dayOfMonth - val firstInMonth = dateTimeInstance.from(year, month, 1) - val startDay = if (now.monthNumber == month && now.year == year) { now } else { firstInMonth } + val firstInMonth = dateTimeProvider.from(year, month, 1) + val startDay = if (now.month == month && now.year == year) { now } else { firstInMonth } if (firstValue >= 10) { val dayOfWeek = toIsoDayOfWeek(firstValue / 10) val index = daysOfWeek[1] / 10 @@ -206,19 +204,20 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, return null } + @Suppress("UNCHECKED_CAST") private fun nearestWorkDayTo(year: Int, month: Int, lastMonthDay: Int, day: Int) : Int { - var checkingDay = dateTimeInstance.from(year, month, day) + var checkingDay = dateTimeProvider.from(year, month, day) if (checkingDay.isoDayOfWeek >= 6) { checkingDay = if (checkingDay.isoDayOfWeek == 6) { if (checkingDay.dayOfMonth > 1) { - checkingDay.minusDays(1) + checkingDay.minusDays(1) as D } else { - checkingDay.plusDays(2) + checkingDay.plusDays(2) as D } } else if (checkingDay.dayOfMonth < lastMonthDay) { - checkingDay.plusDays(1) + checkingDay.plusDays(1) as D } else { - checkingDay.minusDays(2) + checkingDay.minusDays(2) as D } } return checkingDay.dayOfMonth @@ -239,7 +238,7 @@ class Builder>(firstDayOfWeek: WeekDays = WeekDays.Monday, nextYear += 1 nextMonth = 1 } - val firstDayNextMonth = dateTimeInstance.from(nextYear, nextMonth, 1) + val firstDayNextMonth = dateTimeProvider.from(nextYear, nextMonth, 1) return firstDayNextMonth.minusDays(1) } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt index bd89e0c..a30252f 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt @@ -4,11 +4,11 @@ import com.ucasoft.kcron.extensions.minusDays import com.ucasoft.kcron.extensions.plusDays import kotlinx.datetime.* -interface CronDateTime { +interface CronDateTime { val year: Int - val monthNumber: Int + val month: Int val dayOfMonth: Int @@ -20,17 +20,29 @@ interface CronDateTime { val second: Int - fun now() : CronDateTime - fun cast() : T - fun from(year: Int, month: Int, day: Int, hours: Int = 0, minutes: Int = 0, seconds: Int = 0): CronDateTime - fun plusDays(days: Int): CronDateTime fun minusDays(days: Int): CronDateTime } +interface CronDateTimeProvider where D: CronDateTime { + + fun now(): D + + fun from( + year: Int, + month: Int, + day: Int, + hours: Int = 0, + minutes: Int = 0, + seconds: Int = 0 + ): D + + fun from(original: T) : D +} + class CronLocalDateTime: CronDateTime { @@ -52,7 +64,7 @@ class CronLocalDateTime: CronDateTime { override val year: Int get() = dateTime.year - override val monthNumber: Int + override val month: Int get() = dateTime.monthNumber override val dayOfMonth: Int @@ -66,10 +78,17 @@ class CronLocalDateTime: CronDateTime { override val second: Int get() = dateTime.second - override fun now() = CronLocalDateTime() - override fun cast() = dateTime + override fun plusDays(days: Int) = dateTime.plusDays(days).toCronLocalDateTime() + + override fun minusDays(days: Int) = dateTime.minusDays(days).toCronLocalDateTime() +} + +class CronLocalDateTimeProvider : CronDateTimeProvider { + + override fun now() = CronLocalDateTime() + override fun from( year: Int, month: Int, @@ -79,9 +98,8 @@ class CronLocalDateTime: CronDateTime { seconds: Int ) = CronLocalDateTime(year, month, day, hours, minutes, seconds) - override fun plusDays(days: Int) = dateTime.plusDays(days).toCronLocalDateTime() + override fun from(original: LocalDateTime) = original.toCronLocalDateTime() - override fun minusDays(days: Int) = dateTime.minusDays(days).toCronLocalDateTime() } fun LocalDateTime.toCronLocalDateTime() = CronLocalDateTime(this.year, this.monthNumber, this.dayOfMonth, this.hour, this.minute, this.second) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt index 33a564d..6d36955 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt +++ b/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt @@ -2,128 +2,129 @@ package com.ucasoft.kcron.extensions import com.ucasoft.kcron.builders.Builder import com.ucasoft.kcron.builders.CronDateTime +import com.ucasoft.kcron.builders.CronDateTimeProvider import com.ucasoft.kcron.common.* -fun > Builder.anySeconds() : Builder { +fun , P: CronDateTimeProvider> Builder.anySeconds() : Builder { return seconds(TimeGroups.Any, "*") } -fun > Builder.seconds(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.seconds(vararg values: Int) : Builder { return seconds(TimeGroups.Specific, values.joinToString(",")) } -fun > Builder.seconds(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.seconds(at: At) : Builder { return seconds(TimeGroups.EveryStartingAt, at.toString()) } -fun > Builder.seconds(between: IntRange) : Builder { +fun , P: CronDateTimeProvider> Builder.seconds(between: IntRange) : Builder { return seconds(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun > Builder.anyMinutes() : Builder { +fun , P: CronDateTimeProvider> Builder.anyMinutes() : Builder { return minutes(TimeGroups.Any, "*") } -fun > Builder.minutes(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.minutes(vararg values: Int) : Builder { return minutes(TimeGroups.Specific, values.joinToString(",")) } -fun > Builder.minutes(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.minutes(at: At) : Builder { return minutes(TimeGroups.EveryStartingAt, at.toString()) } -fun > Builder.minutes(between: IntRange) : Builder { +fun , P: CronDateTimeProvider> Builder.minutes(between: IntRange) : Builder { return minutes(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun > Builder.anyHours() : Builder { +fun , P: CronDateTimeProvider> Builder.anyHours() : Builder { return hours(TimeGroups.Any, "*") } -fun > Builder.hours(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.hours(vararg values: Int) : Builder { return hours(TimeGroups.Specific, values.joinToString(",")) } -fun > Builder.hours(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.hours(at: At) : Builder { return hours(TimeGroups.EveryStartingAt, at.toString()) } -fun > Builder.hours(between: IntRange) : Builder { +fun , P: CronDateTimeProvider> Builder.hours(between: IntRange) : Builder { return hours(TimeGroups.EveryBetween, "${between.first}-${between.last}") } -fun > Builder.anyDays() : Builder { +fun , P: CronDateTimeProvider> Builder.anyDays() : Builder { return days(DayGroups.Any, "?") } -fun > Builder.days(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.days(vararg values: Int) : Builder { return days(DayGroups.Specific, values.joinToString(",")) } -fun > Builder.days(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.days(at: At) : Builder { return days(DayGroups.EveryStartingAt, at.toString()) } -fun > Builder.lastDay() : Builder { +fun , P: CronDateTimeProvider> Builder.lastDay() : Builder { return days(DayGroups.LastDay, "L") } -fun > Builder.lastWorkDay() : Builder { +fun , P: CronDateTimeProvider> Builder.lastWorkDay() : Builder { return days(DayGroups.LastWeekday, "LW") } -fun > Builder.nearestWorkDay(value: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.nearestWorkDay(value: Int) : Builder { return days(DayGroups.NearestWeekday, "${value}W") } -fun > Builder.anyMonths() : Builder { +fun , P: CronDateTimeProvider> Builder.anyMonths() : Builder { return months(MonthGroups.Any, "*") } -fun > Builder.months(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.months(vararg values: Int) : Builder { return months(MonthGroups.Specific, values.joinToString(",")) } -fun > Builder.months(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.months(at: At) : Builder { return months(MonthGroups.EveryStartingAt, at.toString()) } -fun > Builder.months(between: IntRange) : Builder { +fun , P: CronDateTimeProvider> Builder.months(between: IntRange) : Builder { return months(MonthGroups.EveryBetween, "${between.first}-${between.last}") } -fun > Builder.anyDaysOfWeek(any: String = "*") : Builder { +fun , P: CronDateTimeProvider> Builder.anyDaysOfWeek(any: String = "*") : Builder { return daysOfWeek(DayOfWeekGroups.Any, any) } -fun > Builder.daysOfWeek(vararg values: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.daysOfWeek(vararg values: Int) : Builder { return daysOfWeek(DayOfWeekGroups.Specific, values.joinToString(",") ) } -fun > Builder.daysOfWeek(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.daysOfWeek(at: At) : Builder { return daysOfWeek(DayOfWeekGroups.EveryStartingAt, at.toString()) } -fun > Builder.lastDayOfWeek(value: Int) : Builder { +fun , P: CronDateTimeProvider> Builder.lastDayOfWeek(value: Int) : Builder { return daysOfWeek(DayOfWeekGroups.Last, "${value}L") } -fun > Builder.daysOfWeek(on: On) : Builder { +fun , P: CronDateTimeProvider> Builder.daysOfWeek(on: On) : Builder { return daysOfWeek(DayOfWeekGroups.OfMonth, on.toString()) } -fun > Builder.anyYears() : Builder { +fun , P: CronDateTimeProvider> Builder.anyYears() : Builder { return years(YearGroups.Any, "*") } -fun > Builder.years(vararg values: Int): Builder { +fun , P: CronDateTimeProvider> Builder.years(vararg values: Int): Builder { return years(YearGroups.Specific, values.joinToString(",")) } -fun > Builder.years(at: At) : Builder { +fun , P: CronDateTimeProvider> Builder.years(at: At) : Builder { return years(YearGroups.EveryStartingAt, at.toString()) } -fun > Builder.years(between: IntRange) : Builder { +fun , P: CronDateTimeProvider> Builder.years(between: IntRange) : Builder { return years(YearGroups.EveryBetween, "${between.first}-${between.last}") } \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt index fdacc49..80a39f0 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt +++ b/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt @@ -18,7 +18,7 @@ class BuilderTests { @Test fun buildMany() { - val builder = Builder(dateTimeInstance = CronLocalDateTime()) + val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()) builder.expression.shouldBe("* * * ? * * *") builder.days(1) builder.expression.shouldBe("* * * 1 * ? *") @@ -81,7 +81,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsSunday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Sunday, CronLocalDateTime()) + val builder = Builder(WeekDays.Sunday, CronLocalDateTimeProvider()) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -109,7 +109,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsWednesday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Wednesday, CronLocalDateTime()) + val builder = Builder(WeekDays.Wednesday, CronLocalDateTimeProvider()) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -137,51 +137,51 @@ class BuilderTests { @Test fun iterableShouldStartFromStartDateTimeWhenItInSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2060 00:00:00 val start = LocalDate(2060, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2060 12:00:00 val expected = LocalDate(2060, 1, 1).atTime(12, 0, 0) - /*val actual = builder.asIterable(start).first() - actual.shouldBeEqual(expected)*/ + val actual = builder.asIterable(start).first() + actual.shouldBeEqual(expected) } @Test fun iterableShouldStartFromFirstDatetimeDefinedByCronWhenStartDateTimeIsBeforeSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2010 00:00:00 val start = LocalDate(2010, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2050 12:00:00 (as defined in cron) val expected = LocalDate(2050, 1, 1).atTime(12, 0, 0) - /*val actual = builder.asIterable(start).first() - actual.shouldBeEqual(expected)*/ + val actual = builder.asIterable(start).first() + actual.shouldBeEqual(expected) } @Test fun iterableShouldBeEmptyWhenStartDateTimeIsAfterSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2080 00:00:00 val start = LocalDate(2080, 1, 1).atTime(0, 0, 0) - /*val actual = builder.asIterable(start).take(2) + val actual = builder.asIterable(start).take(2) // expect actual value to be empty because 2080 is out of 2050..2070 range - actual.shouldBeEmpty()*/ + actual.shouldBeEmpty() } @Test fun iterableShouldBeFiniteForCronWithSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeInstance = CronLocalDateTime()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2070 00:00:00 val start = LocalDate(2070, 1, 1).atTime(0, 0, 0) // set expected runs count to be exactly 365 (once per day) val expected = 365 - /* val actual = builder.asIterable(start).toList() - actual.shouldHaveSize(expected)*/ + val actual = builder.asIterable(start).toList() + actual.shouldHaveSize(expected) } } From 3f682345c81b5b0b83b73356a54d5629a46bf3f6 Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 22 Jan 2024 14:54:48 +0100 Subject: [PATCH 3/6] Reformat whole solution --- .gitignore | 8 +- build.gradle.kts | 123 +----------------- buildSrc/build.gradle.kts | 7 + .../src/main/kotlin/PublishingExtension.kt | 7 + buildSrc/src/main/kotlin/publish.gradle.kts | 67 ++++++++++ kcron-abstractions/build.gradle.kts | 32 +++++ .../kcron/abstractions/CronDateTime.kt | 24 ++++ .../abstractions/CronDateTimeProvider.kt | 10 ++ kcron-common/build.gradle.kts | 43 ++++++ .../kotlin/com/ucasoft/kcron/Cron.kt | 21 +++ .../com/ucasoft/kcron/BuildAndParseTests.kt | 6 +- kcron-core/build.gradle.kts | 43 ++++++ .../kotlin/com/ucasoft/kcron/core/Cron.kt | 29 +++++ .../ucasoft/kcron/core}/builders/Builder.kt | 14 +- .../kcron/core}/builders/DaysBuilder.kt | 6 +- .../kcron/core}/builders/DaysOfWeekBuilder.kt | 8 +- .../core}/builders/DelicateIterableApi.kt | 2 +- .../kcron/core}/builders/EveryAtBuilder.kt | 4 +- .../kcron/core}/builders/HoursBuilder.kt | 2 +- .../kcron/core}/builders/MinutesBuilder.kt | 2 +- .../kcron/core}/builders/MonthsBuilder.kt | 4 +- .../kcron/core}/builders/PartBuilder.kt | 4 +- .../kcron/core}/builders/SecondsBuilder.kt | 2 +- .../kcron/core}/builders/TimeBuilder.kt | 4 +- .../kcron/core}/builders/YearsBuilder.kt | 14 +- .../ucasoft/kcron/core}/common/CronGroups.kt | 2 +- .../ucasoft/kcron/core}/common/CronPart.kt | 2 +- .../ucasoft/kcron/core}/common/DayGroups.kt | 2 +- .../kcron/core}/common/DayOfWeekGroups.kt | 2 +- .../ucasoft/kcron/core}/common/MonthGroups.kt | 2 +- .../ucasoft/kcron/core}/common/PartValue.kt | 2 +- .../ucasoft/kcron/core}/common/TimeGroups.kt | 2 +- .../ucasoft/kcron/core}/common/WeekDays.kt | 2 +- .../ucasoft/kcron/core}/common/YearGroups.kt | 2 +- .../kcron/core}/exceptions/UnknownCronPart.kt | 2 +- .../core}/exceptions/WrongCronExpression.kt | 4 +- .../core}/exceptions/WrongPartCombination.kt | 8 +- .../core}/exceptions/WrongPartCombinations.kt | 2 +- .../core}/exceptions/WrongPartExpression.kt | 4 +- .../core}/exceptions/WrongPartsExpression.kt | 2 +- .../com/ucasoft/kcron/core}/extensions/At.kt | 4 +- .../ucasoft/kcron/core}/extensions/Builder.kt | 10 +- .../com/ucasoft/kcron/core}/extensions/On.kt | 4 +- .../core}/parsers/AnySpecificEveryAtParser.kt | 4 +- .../core}/parsers/AnySpecificEveryParser.kt | 4 +- .../kcron/core}/parsers/AnySpecificParser.kt | 4 +- .../ucasoft/kcron/core}/parsers/BaseParser.kt | 6 +- .../kcron/core/parsers/CombinationRule.kt | 6 + .../kcron/core}/parsers/DaysOfWeekParser.kt | 6 +- .../ucasoft/kcron/core}/parsers/DaysParser.kt | 6 +- .../kcron/core}/parsers/HoursParser.kt | 4 +- .../kcron/core}/parsers/MonthsParser.kt | 6 +- .../ucasoft/kcron/core/parsers/ParseResult.kt | 9 ++ .../com/ucasoft/kcron/core}/parsers/Parser.kt | 16 ++- .../core}/parsers/SecondsMinutesParser.kt | 4 +- .../ucasoft/kcron/core}/parsers/TimeParser.kt | 6 +- .../kcron/core}/parsers/YearsParser.kt | 6 +- .../ucasoft/kcron/core}/settings/Settings.kt | 4 +- .../ucasoft/kcron/core}/settings/Version.kt | 2 +- .../ucasoft/kcron/core/BuildAndParseTests.kt | 69 ++++++++++ .../kcron/core}/builders/BuilderTests.kt | 27 ++-- .../kcron/core}/builders/DaysBuilderTests.kt | 6 +- .../core}/builders/DaysOfWeekBuilderTests.kt | 8 +- .../kcron/core}/builders/HoursBuilderTests.kt | 4 +- .../core}/builders/MinutesBuilderTests.kt | 4 +- .../core}/builders/MonthsBuilderTests.kt | 4 +- .../core}/builders/SecondsBuilderTests.kt | 4 +- .../kcron/core}/builders/YearsBuilderTests.kt | 17 +-- .../kcron/core/parsers/DayOfWeekValueGroup.kt | 5 + .../kcron/core/parsers/DayValueGroup.kt | 5 + .../core}/parsers/DaysOfWeekPartTests.kt | 4 +- .../kcron/core}/parsers/DaysPartTests.kt | 4 +- .../kcron/core}/parsers/HoursPartTests.kt | 4 +- .../kcron/core/parsers/MonthPartTests.kt | 75 +++++++++++ .../kcron/core/parsers/MonthValueGroup.kt | 5 + .../kcron/core}/parsers/ParserTests.kt | 35 +++-- .../kcron/core}/parsers/SecondsPartTests.kt | 6 +- .../kcron/core/parsers/TimeValueGroup.kt | 5 + .../kcron/core}/parsers/YearPartTests.kt | 8 +- .../kcron/core/parsers/YearValueGroup.kt | 5 + kcron-kotlinx-datetime/build.gradle.kts | 37 ++++++ .../kotlinx/datetime/CronLocalDateTime.kt | 45 +++++++ .../datetime/CronLocalDateTimeExtensions.kt | 5 +- .../datetime/CronLocalDateTimeProvider.kt | 15 +++ settings.gradle.kts | 12 +- .../kotlin/com/ucasoft/kcron/Cron.kt | 33 ----- .../ucasoft/kcron/builders/CronDateTime.kt | 105 --------------- .../ucasoft/kcron/parsers/CombinationRule.kt | 6 - .../com/ucasoft/kcron/parsers/ParseResult.kt | 9 -- .../kcron/parsers/DayOfWeekValueGroup.kt | 5 - .../ucasoft/kcron/parsers/DayValueGroup.kt | 5 - .../ucasoft/kcron/parsers/MonthPartTests.kt | 75 ----------- .../ucasoft/kcron/parsers/MonthValueGroup.kt | 5 - .../ucasoft/kcron/parsers/TimeValueGroup.kt | 5 - .../ucasoft/kcron/parsers/YearValueGroup.kt | 5 - 95 files changed, 763 insertions(+), 545 deletions(-) create mode 100644 buildSrc/build.gradle.kts create mode 100644 buildSrc/src/main/kotlin/PublishingExtension.kt create mode 100644 buildSrc/src/main/kotlin/publish.gradle.kts create mode 100644 kcron-abstractions/build.gradle.kts create mode 100644 kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTime.kt create mode 100644 kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTimeProvider.kt create mode 100644 kcron-common/build.gradle.kts create mode 100644 kcron-common/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt rename {src => kcron-common/src}/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt (93%) create mode 100644 kcron-core/build.gradle.kts create mode 100644 kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/Cron.kt rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/Builder.kt (95%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/DaysBuilder.kt (88%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/DaysOfWeekBuilder.kt (91%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/DelicateIterableApi.kt (84%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/EveryAtBuilder.kt (92%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/HoursBuilder.kt (79%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/MinutesBuilder.kt (75%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/MonthsBuilder.kt (90%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/PartBuilder.kt (77%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/SecondsBuilder.kt (75%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/TimeBuilder.kt (77%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/builders/YearsBuilder.kt (50%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/CronGroups.kt (54%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/CronPart.kt (84%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/DayGroups.kt (84%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/DayOfWeekGroups.kt (81%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/MonthGroups.kt (80%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/PartValue.kt (60%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/TimeGroups.kt (80%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/WeekDays.kt (83%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/common/YearGroups.kt (80%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/UnknownCronPart.kt (64%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/WrongCronExpression.kt (65%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/WrongPartCombination.kt (73%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/WrongPartCombinations.kt (85%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/WrongPartExpression.kt (68%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/exceptions/WrongPartsExpression.kt (81%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/extensions/At.kt (79%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/extensions/Builder.kt (95%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/extensions/On.kt (78%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/AnySpecificEveryAtParser.kt (89%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/AnySpecificEveryParser.kt (90%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/AnySpecificParser.kt (89%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/BaseParser.kt (88%) create mode 100644 kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/DaysOfWeekParser.kt (78%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/DaysParser.kt (74%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/HoursParser.kt (52%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/MonthsParser.kt (71%) create mode 100644 kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/ParseResult.kt rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/Parser.kt (90%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/SecondsMinutesParser.kt (55%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/TimeParser.kt (68%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/parsers/YearsParser.kt (65%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/settings/Settings.kt (55%) rename {src/commonMain/kotlin/com/ucasoft/kcron => kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core}/settings/Version.kt (68%) create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/BuildAndParseTests.kt rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/BuilderTests.kt (88%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/DaysBuilderTests.kt (90%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/DaysOfWeekBuilderTests.kt (90%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/HoursBuilderTests.kt (90%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/MinutesBuilderTests.kt (91%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/MonthsBuilderTests.kt (91%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/SecondsBuilderTests.kt (91%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/builders/YearsBuilderTests.kt (70%) create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayOfWeekValueGroup.kt create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayValueGroup.kt rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/DaysOfWeekPartTests.kt (96%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/DaysPartTests.kt (96%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/HoursPartTests.kt (95%) create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthValueGroup.kt rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/ParserTests.kt (59%) rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/SecondsPartTests.kt (93%) create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/TimeValueGroup.kt rename {src/commonTest/kotlin/com/ucasoft/kcron => kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core}/parsers/YearPartTests.kt (89%) create mode 100644 kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearValueGroup.kt create mode 100644 kcron-kotlinx-datetime/build.gradle.kts create mode 100644 kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTime.kt rename src/commonMain/kotlin/com/ucasoft/kcron/extensions/LocalDateTime.kt => kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeExtensions.kt (80%) create mode 100644 kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeProvider.kt delete mode 100644 src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt delete mode 100644 src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt delete mode 100644 src/commonMain/kotlin/com/ucasoft/kcron/parsers/CombinationRule.kt delete mode 100644 src/commonMain/kotlin/com/ucasoft/kcron/parsers/ParseResult.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayOfWeekValueGroup.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayValueGroup.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthPartTests.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthValueGroup.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/TimeValueGroup.kt delete mode 100644 src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearValueGroup.kt diff --git a/.gitignore b/.gitignore index 58f4782..840390c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ # Project exclude paths -/.gradle/ -/.idea/ -/build/ -/build/classes/kotlin/jvm/main/ -/build/classes/kotlin/jvm/test/ \ No newline at end of file +.gradle/ +.idea/ +build/ \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index b2aebc9..6292eb0 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,125 +1,10 @@ -plugins { - alias(libs.plugins.multiplatform) - id("maven-publish") - id("signing") -} +allprojects { -group = "com.ucasoft.kcron" -version = "0.9.2" + group = "com.ucasoft.kcron" -repositories { - mavenCentral() -} -kotlin { - jvm { - compilations.all { - kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() - } - } - linuxX64() - linuxArm64() - mingwX64() - macosX64() - macosArm64() - js(IR) { - browser() - nodejs() - } - iosX64() - iosArm64() - iosSimulatorArm64() - sourceSets { - commonMain { - dependencies { - implementation(libs.kotlinx.datetime) - } - } - commonTest { - dependencies { - implementation(kotlin("test-common")) - implementation(kotlin("test-annotations-common")) - implementation(libs.kotest.assetions) - } - } - val jsTest by getting { - dependencies { - implementation(kotlin("test-js")) - } - } - val jvmTest by getting { - dependencies { - implementation(kotlin("test-junit")) - } - } - } -} - -val stubSources by tasks.creating(Jar::class) { - archiveClassifier.set("sources") -} - -val stubJavadoc by tasks.creating(Jar::class) { - archiveClassifier.set("javadoc") -} + version = "0.10.0" -val sourceJar by tasks.creating(Jar::class) { - archiveClassifier.set("sources") - from(kotlin.sourceSets.commonMain.get().kotlin) -} - -publishing { - publications.configureEach { - if (this is MavenPublication) { - if (name != "kotlinMultiplatform") { - artifact(stubJavadoc) - } - pom { - name.set("KCron Common") - description.set("Cron realization for Kotlin Multiplatform") - url.set("https://github.com/Scogun/kcron-common") - licenses { - license { - name.set("The Apache License, Version 2.0") - url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") - } - } - developers { - developer { - id.set("Scogun") - name.set("Sergey Antonov") - email.set("SAntonov@ucasoft.com") - } - developer { - id.set("Myshkouski") - name.set("Alexei Myshkouski") - email.set("alexeimyshkouski@gmail.com") - } - } - scm { - connection.set("scm:git:git://github.com/Scogun/kcron-common.git") - developerConnection.set("scm:git:ssh://github.com:Scogun/kcron-common.git") - url.set("https://github.com/Scogun/kcron-common") - } - } - } - } repositories { - maven { - name = "MavenCentral" - url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") - credentials { - username = System.getenv("MAVEN_USERNAME") - password = System.getenv("MAVEN_PASSWORD") - } - } + mavenCentral() } -} - -signing { - sign(publishing.publications) -} - -tasks.withType().configureEach { - val signingTasks = tasks.withType() - mustRunAfter(signingTasks) } \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..b22ed73 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/PublishingExtension.kt b/buildSrc/src/main/kotlin/PublishingExtension.kt new file mode 100644 index 0000000..812c782 --- /dev/null +++ b/buildSrc/src/main/kotlin/PublishingExtension.kt @@ -0,0 +1,7 @@ +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.property + +open class PublishingExtension(factory: ObjectFactory) { + val name = factory.property() + val description = factory.property() +} \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/publish.gradle.kts b/buildSrc/src/main/kotlin/publish.gradle.kts new file mode 100644 index 0000000..ebdb19e --- /dev/null +++ b/buildSrc/src/main/kotlin/publish.gradle.kts @@ -0,0 +1,67 @@ +plugins { + `maven-publish` + signing +} + +val libraryData = extensions.create("libraryData", PublishingExtension::class) + +val stubJavadoc by tasks.creating(Jar::class) { + archiveClassifier.set("javadoc") +} + +publishing { + publications.configureEach { + if (this is MavenPublication) { + if (name != "kotlinMultiplatform") { + artifact(stubJavadoc) + } + pom { + name.set(libraryData.name) + description.set(libraryData.description) + url.set("https://github.com/Scogun/kcron-common") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("https://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("Scogun") + name.set("Sergey Antonov") + email.set("SAntonov@ucasoft.com") + } + developer { + id.set("Myshkouski") + name.set("Alexei Myshkouski") + email.set("alexeimyshkouski@gmail.com") + } + } + scm { + connection.set("scm:git:git://github.com/Scogun/kcron-common.git") + developerConnection.set("scm:git:ssh://github.com:Scogun/kcron-common.git") + url.set("https://github.com/Scogun/kcron-common") + } + } + } + } + repositories { + maven { + name = "MavenCentral" + url = uri("https://oss.sonatype.org/service/local/staging/deploy/maven2/") + credentials { + username = System.getenv("MAVEN_USERNAME") + password = System.getenv("MAVEN_PASSWORD") + } + } + } +} + +signing { + sign(publishing.publications) +} + +tasks.withType().configureEach { + val signingTasks = tasks.withType() + mustRunAfter(signingTasks) +} \ No newline at end of file diff --git a/kcron-abstractions/build.gradle.kts b/kcron-abstractions/build.gradle.kts new file mode 100644 index 0000000..db63bfb --- /dev/null +++ b/kcron-abstractions/build.gradle.kts @@ -0,0 +1,32 @@ +plugins { + alias(libs.plugins.multiplatform) + id("publish") +} + +kotlin { + jvm { + compilations.all { + kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } + linuxX64() + linuxArm64() + mingwX64() + macosX64() + macosArm64() + js(IR) { + browser() + nodejs() + } + iosX64() + iosArm64() + iosSimulatorArm64() + sourceSets { + commonMain + } +} + +libraryData { + name.set("KCron Abstractions") + description.set("Abstractions for Kotlin Multiplatform Cron realization") +} \ No newline at end of file diff --git a/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTime.kt b/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTime.kt new file mode 100644 index 0000000..c47faf1 --- /dev/null +++ b/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTime.kt @@ -0,0 +1,24 @@ +package com.ucasoft.kcron.abstractions + +interface CronDateTime { + + val year: Int + + val month: Int + + val dayOfMonth: Int + + val isoDayOfWeek: Int + + val hour: Int + + val minute: Int + + val second: Int + + fun cast() : T + + fun plusDays(days: Int): CronDateTime + + fun minusDays(days: Int): CronDateTime +} \ No newline at end of file diff --git a/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTimeProvider.kt b/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTimeProvider.kt new file mode 100644 index 0000000..ffb06b7 --- /dev/null +++ b/kcron-abstractions/src/commonMain/kotlin/com/ucasoft/kcron/abstractions/CronDateTimeProvider.kt @@ -0,0 +1,10 @@ +package com.ucasoft.kcron.abstractions + +interface CronDateTimeProvider where D: CronDateTime { + + fun now(): D + + fun from(year: Int, month: Int, day: Int, hours: Int = 0, minutes: Int = 0, seconds: Int = 0): D + + fun from(original: T) : D +} \ No newline at end of file diff --git a/kcron-common/build.gradle.kts b/kcron-common/build.gradle.kts new file mode 100644 index 0000000..918767f --- /dev/null +++ b/kcron-common/build.gradle.kts @@ -0,0 +1,43 @@ +plugins { + alias(libs.plugins.multiplatform) + id("publish") +} + +kotlin { + jvm { + compilations.all { + kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } + linuxX64() + linuxArm64() + mingwX64() + macosX64() + macosArm64() + js(IR) { + browser() + nodejs() + } + iosX64() + iosArm64() + iosSimulatorArm64() + sourceSets { + commonMain { + dependencies { + implementation(project(":kcron-core")) + implementation(project(":kcron-kotlinx-datetime")) + } + } + commonTest { + dependencies { + implementation(kotlin("test")) + implementation(libs.kotest.assetions) + } + } + } +} + +libraryData { + name.set("KCron Common") + description.set("Cron realization for Kotlin Multiplatform with Kotlinx DateTime Provider") +} \ No newline at end of file diff --git a/kcron-common/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt b/kcron-common/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt new file mode 100644 index 0000000..80cfc43 --- /dev/null +++ b/kcron-common/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt @@ -0,0 +1,21 @@ +package com.ucasoft.kcron + +import com.ucasoft.kcron.core.common.WeekDays +import com.ucasoft.kcron.core.settings.Settings +import com.ucasoft.kcron.kotlinx.datetime.CronLocalDateTimeProvider +import com.ucasoft.kcron.core.Cron as CoreCron + +object Cron { + + private val dateTimeProvider = CronLocalDateTimeProvider() + + fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) = CoreCron.parseAndBuild(expression, dateTimeProvider, block) + + fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday) = CoreCron.builder(dateTimeProvider, firstDayOfWeek) +} + +@Deprecated( + message = "Class name should not explicitly tell it's written in Kotlin (with starting 'K'). It would be compiled in Java bytecode, Javascript, etc.", + replaceWith = ReplaceWith("Cron") +) +typealias KCron = Cron \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt b/kcron-common/src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt similarity index 93% rename from src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt rename to kcron-common/src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt index a78970b..a901cfa 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt +++ b/kcron-common/src/commonTest/kotlin/com/ucasoft/kcron/BuildAndParseTests.kt @@ -1,7 +1,7 @@ package com.ucasoft.kcron -import com.ucasoft.kcron.exceptions.WrongCronExpression -import com.ucasoft.kcron.settings.Version +import com.ucasoft.kcron.core.exceptions.WrongCronExpression +import com.ucasoft.kcron.core.settings.Version import io.kotest.assertions.throwables.shouldThrowWithMessage import io.kotest.matchers.nulls.shouldNotBeNull import io.kotest.matchers.shouldBe @@ -13,7 +13,7 @@ import kotlin.test.Test class BuildAndParseTests { - private var currentYear : Int = 2023 + private var currentYear : Int = 2024 private val modernCronExpression = "30 * * ? * * 2050" diff --git a/kcron-core/build.gradle.kts b/kcron-core/build.gradle.kts new file mode 100644 index 0000000..6b2d9dc --- /dev/null +++ b/kcron-core/build.gradle.kts @@ -0,0 +1,43 @@ +plugins { + alias(libs.plugins.multiplatform) + id("publish") +} + +kotlin { + jvm { + compilations.all { + kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } + linuxX64() + linuxArm64() + mingwX64() + macosX64() + macosArm64() + js(IR) { + browser() + nodejs() + } + iosX64() + iosArm64() + iosSimulatorArm64() + sourceSets { + commonMain { + dependencies { + api(project(":kcron-abstractions")) + } + } + commonTest { + dependencies { + implementation(kotlin("test")) + implementation(project(":kcron-kotlinx-datetime")) + implementation(libs.kotest.assetions) + } + } + } +} + +libraryData { + name.set("KCron Core") + description.set("Cron realization for Kotlin Multiplatform") +} \ No newline at end of file diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/Cron.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/Cron.kt new file mode 100644 index 0000000..7cc7976 --- /dev/null +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/Cron.kt @@ -0,0 +1,29 @@ +package com.ucasoft.kcron.core + +import com.ucasoft.kcron.abstractions.CronDateTime +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import com.ucasoft.kcron.core.builders.Builder +import com.ucasoft.kcron.core.common.WeekDays +import com.ucasoft.kcron.core.parsers.Parser +import com.ucasoft.kcron.core.settings.Settings + +object Cron { + + fun , P : CronDateTimeProvider> parseAndBuild( + expression: String, + provider: P, + block: (Settings) -> Unit = {} + ): Builder { + val settings = Settings() + block.invoke(settings) + val parseResult = Parser().parse(expression, settings.version) + return Builder(provider, settings.firstDayOfWeek).build(parseResult.parts) + } + + fun , P : CronDateTimeProvider> builder( + provider: P, + firstDayOfWeek: WeekDays = WeekDays.Monday + ): Builder { + return Builder(provider, firstDayOfWeek) + } +} diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt similarity index 95% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt index e185f7c..97a8a64 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/Builder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt @@ -1,8 +1,10 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.* +import com.ucasoft.kcron.abstractions.CronDateTime +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import com.ucasoft.kcron.core.common.* -class Builder, P: CronDateTimeProvider>(firstDayOfWeek: WeekDays = WeekDays.Monday, private val dateTimeProvider: P) { +class Builder, P: CronDateTimeProvider>(private val dateTimeProvider: P, firstDayOfWeek: WeekDays = WeekDays.Monday) { private val partBuilders = mapOf( CronPart.Seconds to SecondsBuilder(), @@ -11,7 +13,7 @@ class Builder, P: CronDateTimeProvider>(firstDayOfWe CronPart.Days to DaysBuilder(), CronPart.Months to MonthsBuilder(), CronPart.DaysOfWeek to DaysOfWeekBuilder(firstDayOfWeek), - CronPart.Years to YearsBuilder() + CronPart.Years to YearsBuilder(dateTimeProvider) ) init { @@ -29,7 +31,7 @@ class Builder, P: CronDateTimeProvider>(firstDayOfWe get() = asIterable().firstOrNull() val expression: String - get() = partBuilders.values.joinToString(" ") { builder -> builder.value } + get() = partBuilders.values.joinToString(" ") { it.value } private val firstDayOfWeekIndex = WeekDays.entries.indexOf(firstDayOfWeek) @@ -86,7 +88,7 @@ class Builder, P: CronDateTimeProvider>(firstDayOfWe val internalStart = dateTimeProvider.from(start) return Iterable { iterator { - for (year in (partBuilders.getValue(CronPart.Years) as YearsBuilder).years.filter { y -> y >= internalStart.year }) { + for (year in (partBuilders.getValue(CronPart.Years) as YearsBuilder<*>).years.filter { y -> y >= internalStart.year }) { for (month in (partBuilders.getValue(CronPart.Months) as MonthsBuilder).months.filter { m -> m >= internalStart.month || year > internalStart.year}) { for (day in calculateDays(year, month, (partBuilders.getValue(CronPart.DaysOfWeek) as DaysOfWeekBuilder).daysOfWeek, (partBuilders.getValue(CronPart.Days) as DaysBuilder).days, internalStart)) { for (hour in (partBuilders.getValue(CronPart.Hours) as HoursBuilder).hours.filter { h -> h >= internalStart.hour || day > internalStart.dayOfMonth || month > internalStart.month || year > internalStart.year }) { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysBuilder.kt similarity index 88% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysBuilder.kt index 2f162e6..d18b41d 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysBuilder.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.DayGroups -import com.ucasoft.kcron.exceptions.UnknownCronPart +import com.ucasoft.kcron.core.common.DayGroups +import com.ucasoft.kcron.core.exceptions.UnknownCronPart class DaysBuilder : PartBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilder.kt similarity index 91% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilder.kt index 209df12..296a14b 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilder.kt @@ -1,8 +1,8 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.DayOfWeekGroups -import com.ucasoft.kcron.common.WeekDays -import com.ucasoft.kcron.exceptions.UnknownCronPart +import com.ucasoft.kcron.core.common.DayOfWeekGroups +import com.ucasoft.kcron.core.common.WeekDays +import com.ucasoft.kcron.core.exceptions.UnknownCronPart class DaysOfWeekBuilder(private val firstWeekDay: WeekDays = WeekDays.Monday) : PartBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DelicateIterableApi.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DelicateIterableApi.kt similarity index 84% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/DelicateIterableApi.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DelicateIterableApi.kt index f313f28..3f4c04b 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/DelicateIterableApi.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/DelicateIterableApi.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders @RequiresOptIn( message = "This method returns Iterable that possibly infinite. Be sure to limit elements count when collecting result.", diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/EveryAtBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/EveryAtBuilder.kt similarity index 92% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/EveryAtBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/EveryAtBuilder.kt index 77fad73..11e5b54 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/EveryAtBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/EveryAtBuilder.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.CronGroups +import com.ucasoft.kcron.core.common.CronGroups abstract class EveryAtBuilder : PartBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/HoursBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/HoursBuilder.kt similarity index 79% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/HoursBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/HoursBuilder.kt index effab28..8605cbb 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/HoursBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/HoursBuilder.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders class HoursBuilder : TimeBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/MinutesBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilder.kt similarity index 75% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/MinutesBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilder.kt index f129c4c..a70d2df 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/MinutesBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilder.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders class MinutesBuilder : TimeBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/MonthsBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilder.kt similarity index 90% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/MonthsBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilder.kt index 1bc8553..7a47f19 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/MonthsBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilder.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.MonthGroups +import com.ucasoft.kcron.core.common.MonthGroups class MonthsBuilder : EveryAtBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/PartBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/PartBuilder.kt similarity index 77% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/PartBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/PartBuilder.kt index 75fd5a9..f421e7a 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/PartBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/PartBuilder.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.CronGroups +import com.ucasoft.kcron.core.common.CronGroups abstract class PartBuilder { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/SecondsBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilder.kt similarity index 75% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/SecondsBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilder.kt index d7e9361..5e7455a 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/SecondsBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilder.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders class SecondsBuilder : TimeBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/TimeBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/TimeBuilder.kt similarity index 77% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/TimeBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/TimeBuilder.kt index 8c69c41..db2d641 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/TimeBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/TimeBuilder.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.TimeGroups abstract class TimeBuilder : EveryAtBuilder() { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/YearsBuilder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/YearsBuilder.kt similarity index 50% rename from src/commonMain/kotlin/com/ucasoft/kcron/builders/YearsBuilder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/YearsBuilder.kt index a3fc7b4..f5e0bdf 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/YearsBuilder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/YearsBuilder.kt @@ -1,11 +1,9 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.YearGroups -import kotlinx.datetime.Clock -import kotlinx.datetime.TimeZone -import kotlinx.datetime.toLocalDateTime +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import com.ucasoft.kcron.core.common.YearGroups -class YearsBuilder : EveryAtBuilder() { +class YearsBuilder>(private val provider: P) : EveryAtBuilder() { val years : List get() { @@ -14,8 +12,8 @@ class YearsBuilder : EveryAtBuilder() { override val defaultStart: Int get() { - val now = Clock.System.now() - return now.toLocalDateTime(TimeZone.currentSystemDefault()).year + val now = provider.now() + return now.year } override val defaultEnd = 2099 diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/CronGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronGroups.kt similarity index 54% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/CronGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronGroups.kt index dba9ae9..a62fd27 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/CronGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common interface CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/CronPart.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronPart.kt similarity index 84% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/CronPart.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronPart.kt index 5aae1c6..4224598 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/CronPart.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/CronPart.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class CronPart(val partName: String) { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/DayGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayGroups.kt similarity index 84% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/DayGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayGroups.kt index d0e02f6..845bccd 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/DayGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class DayGroups(override val index: Int) : CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/DayOfWeekGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayOfWeekGroups.kt similarity index 81% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/DayOfWeekGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayOfWeekGroups.kt index 648c2e7..26d48d4 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/DayOfWeekGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/DayOfWeekGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class DayOfWeekGroups(override val index: Int) : CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/MonthGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/MonthGroups.kt similarity index 80% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/MonthGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/MonthGroups.kt index 84b890b..279b1b5 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/MonthGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/MonthGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class MonthGroups(override val index: Int) : CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/PartValue.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/PartValue.kt similarity index 60% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/PartValue.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/PartValue.kt index 4b8e692..3f82133 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/PartValue.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/PartValue.kt @@ -1,3 +1,3 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common class PartValue(val type: CronGroups, val value: String) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/TimeGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/TimeGroups.kt similarity index 80% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/TimeGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/TimeGroups.kt index a533626..a67927e 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/TimeGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/TimeGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class TimeGroups(override val index: Int) : CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/WeekDays.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/WeekDays.kt similarity index 83% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/WeekDays.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/WeekDays.kt index c1e721c..d5b5c33 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/WeekDays.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/WeekDays.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class WeekDays(val shortName: String) { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/common/YearGroups.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/YearGroups.kt similarity index 80% rename from src/commonMain/kotlin/com/ucasoft/kcron/common/YearGroups.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/YearGroups.kt index 1211f96..64af9cb 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/common/YearGroups.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/common/YearGroups.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.common +package com.ucasoft.kcron.core.common enum class YearGroups(override val index: Int) : CronGroups { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/UnknownCronPart.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/UnknownCronPart.kt similarity index 64% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/UnknownCronPart.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/UnknownCronPart.kt index 8cd756d..0e27f94 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/UnknownCronPart.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/UnknownCronPart.kt @@ -1,3 +1,3 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions class UnknownCronPart(part: String) : Throwable("Unknown Cron part $part!") \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongCronExpression.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongCronExpression.kt similarity index 65% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongCronExpression.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongCronExpression.kt index 9deb78d..205a270 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongCronExpression.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongCronExpression.kt @@ -1,5 +1,5 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions -import com.ucasoft.kcron.settings.Version +import com.ucasoft.kcron.core.settings.Version class WrongCronExpression(expression: String, version: Version) : Throwable("Expression $expression is not ${if (version != Version.Auto) "$version " else ""}Cron one!") diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombination.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombination.kt similarity index 73% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombination.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombination.kt index 9d38ccb..0e573fe 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombination.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombination.kt @@ -1,8 +1,8 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.parsers.CombinationRule -import com.ucasoft.kcron.common.PartValue +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.PartValue +import com.ucasoft.kcron.core.parsers.CombinationRule class WrongPartCombination( private val part: MutableMap.MutableEntry, diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombinations.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombinations.kt similarity index 85% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombinations.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombinations.kt index 1684390..b78f475 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartCombinations.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartCombinations.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions class WrongPartCombinations(combinationExceptions: List) : Throwable("Multiple combination rules have been violated: ${combinationExceptions.joinToString { ce -> "${ce.firstPartName} -> ${ce.secondPartName}" }}!") diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartExpression.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartExpression.kt similarity index 68% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartExpression.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartExpression.kt index 7644b8b..6c2d5e0 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartExpression.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartExpression.kt @@ -1,5 +1,5 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions -import com.ucasoft.kcron.parsers.BaseParser +import com.ucasoft.kcron.core.parsers.BaseParser class WrongPartExpression(partValue: String, internal val specificParser: BaseParser<*>) : Throwable("Value $partValue is not the valid expression for the ${specificParser.part.partName} part!") diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartsExpression.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartsExpression.kt similarity index 81% rename from src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartsExpression.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartsExpression.kt index 8308e3a..8f71998 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/exceptions/WrongPartsExpression.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/exceptions/WrongPartsExpression.kt @@ -1,3 +1,3 @@ -package com.ucasoft.kcron.exceptions +package com.ucasoft.kcron.core.exceptions class WrongPartsExpression(innerExceptions: List) : Throwable("Parts ${innerExceptions.map { ie -> ie.specificParser.part }.joinToString()} contain wrong expressions!") diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/At.kt similarity index 79% rename from src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/At.kt index e7c4bd9..931e476 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/At.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/At.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.extensions +package com.ucasoft.kcron.core.extensions -import com.ucasoft.kcron.common.WeekDays +import com.ucasoft.kcron.core.common.WeekDays class At(private val every: Int, private val starting: String) { constructor(every: Int, starting: WeekDays) : this(every, starting.shortName) diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/Builder.kt similarity index 95% rename from src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/Builder.kt index 6d36955..94156c2 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/Builder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/Builder.kt @@ -1,9 +1,9 @@ -package com.ucasoft.kcron.extensions +package com.ucasoft.kcron.core.extensions -import com.ucasoft.kcron.builders.Builder -import com.ucasoft.kcron.builders.CronDateTime -import com.ucasoft.kcron.builders.CronDateTimeProvider -import com.ucasoft.kcron.common.* +import com.ucasoft.kcron.abstractions.CronDateTime +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import com.ucasoft.kcron.core.builders.Builder +import com.ucasoft.kcron.core.common.* fun , P: CronDateTimeProvider> Builder.anySeconds() : Builder { return seconds(TimeGroups.Any, "*") diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/On.kt similarity index 78% rename from src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/On.kt index 0ab50f6..b02d94e 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/On.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/extensions/On.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.extensions +package com.ucasoft.kcron.core.extensions -import com.ucasoft.kcron.common.WeekDays +import com.ucasoft.kcron.core.common.WeekDays class On(private val dayOfWeek: String, private val index: Int) { constructor(dayOfWeek: WeekDays, index: Int) : this(dayOfWeek.shortName, index) diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryAtParser.kt similarity index 89% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryAtParser.kt index 0151de2..f9118e8 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryAtParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryAtParser.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronGroups +import com.ucasoft.kcron.core.common.CronGroups abstract class AnySpecificEveryAtParser( anyPattern: String, diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryParser.kt similarity index 90% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryParser.kt index d191276..b84820c 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificEveryParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificEveryParser.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronGroups +import com.ucasoft.kcron.core.common.CronGroups abstract class AnySpecificEveryParser( anyPattern: String, diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificParser.kt similarity index 89% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificParser.kt index 3fd8c23..ff20d32 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/AnySpecificParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/AnySpecificParser.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronGroups +import com.ucasoft.kcron.core.common.CronGroups abstract class AnySpecificParser( private val anyPattern: String, diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/BaseParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/BaseParser.kt similarity index 88% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/BaseParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/BaseParser.kt index 6fb72ea..dbd6966 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/BaseParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/BaseParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronGroups -import com.ucasoft.kcron.common.CronPart +import com.ucasoft.kcron.core.common.CronGroups +import com.ucasoft.kcron.core.common.CronPart import kotlin.enums.EnumEntries abstract class BaseParser where T : Enum, T: CronGroups { diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt new file mode 100644 index 0000000..dc8519d --- /dev/null +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt @@ -0,0 +1,6 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.CronGroups +import com.ucasoft.kcron.core.common.CronPart + +class CombinationRule(val part: CronPart, val type: CronGroups, val dependencies: List? = null) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekParser.kt similarity index 78% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekParser.kt index ec29961..3cb47c7 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.DayOfWeekGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.DayOfWeekGroups class DaysOfWeekParser : AnySpecificEveryAtParser("[*?]", "[1-7]", listOf("SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT").joinToString("|")) { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysParser.kt similarity index 74% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysParser.kt index 8ed349f..931fc7a 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/DaysParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/DaysParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.DayGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.DayGroups class DaysParser : AnySpecificEveryAtParser("\\?", "[1-9]|[1-2][0-9]|3[0-1]") { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/HoursParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/HoursParser.kt similarity index 52% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/HoursParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/HoursParser.kt index b2955e6..5839893 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/HoursParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/HoursParser.kt @@ -1,5 +1,5 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart +import com.ucasoft.kcron.core.common.CronPart class HoursParser : TimeParser(CronPart.Hours,"[0-9]|1[0-9]|2[0-3]", "[0-9]|1[0-9]|2[0-4]") \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/MonthsParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/MonthsParser.kt similarity index 71% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/MonthsParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/MonthsParser.kt index 4691def..64305cd 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/MonthsParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/MonthsParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.MonthGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.MonthGroups class MonthsParser : AnySpecificEveryParser("\\*", "[1-9]|1[0-2]", listOf("JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC").joinToString("|")) { diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/ParseResult.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/ParseResult.kt new file mode 100644 index 0000000..81f5960 --- /dev/null +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/ParseResult.kt @@ -0,0 +1,9 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.PartValue + +class ParseResult { + + val parts = mutableMapOf() +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/Parser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt similarity index 90% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/Parser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt index 2cb1b65..25b8485 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/Parser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt @@ -1,8 +1,8 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.* -import com.ucasoft.kcron.exceptions.* -import com.ucasoft.kcron.settings.Version +import com.ucasoft.kcron.core.common.* +import com.ucasoft.kcron.core.exceptions.* +import com.ucasoft.kcron.core.settings.Version class Parser { @@ -85,7 +85,13 @@ class Parser { for (dependency in rule.dependencies!!) { val secondPart = parts[dependency.part] if (secondPart!!.type != dependency.type) { - combinationExceptions.add(WrongPartCombination(part, dependency, secondPart)) + combinationExceptions.add( + WrongPartCombination( + part, + dependency, + secondPart + ) + ) } } } diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/SecondsMinutesParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/SecondsMinutesParser.kt similarity index 55% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/SecondsMinutesParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/SecondsMinutesParser.kt index dff1f7c..cb36ed6 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/SecondsMinutesParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/SecondsMinutesParser.kt @@ -1,5 +1,5 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart +import com.ucasoft.kcron.core.common.CronPart class SecondsMinutesParser(part: CronPart) : TimeParser(part,"[0-9]|[1-5][0-9]", "[0-9]|[1-5][0-9]|60") \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/TimeParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/TimeParser.kt similarity index 68% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/TimeParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/TimeParser.kt index 0a3f907..a9ccecf 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/TimeParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/TimeParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.TimeGroups abstract class TimeParser(override val part: CronPart, startingPattern: String, everyPattern: String) : AnySpecificEveryParser("\\*", startingPattern, "", everyPattern) { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/YearsParser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/YearsParser.kt similarity index 65% rename from src/commonMain/kotlin/com/ucasoft/kcron/parsers/YearsParser.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/YearsParser.kt index 83cbd87..7f349fe 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/YearsParser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/YearsParser.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.YearGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.YearGroups class YearsParser: AnySpecificEveryParser("\\*", "20[2-9][0-9]", "", "[0-9]|[1-9][1-9]|100") { diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/settings/Settings.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Settings.kt similarity index 55% rename from src/commonMain/kotlin/com/ucasoft/kcron/settings/Settings.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Settings.kt index da0de94..a8e98c9 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/settings/Settings.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Settings.kt @@ -1,5 +1,5 @@ -package com.ucasoft.kcron.settings +package com.ucasoft.kcron.core.settings -import com.ucasoft.kcron.common.WeekDays +import com.ucasoft.kcron.core.common.WeekDays data class Settings(var firstDayOfWeek: WeekDays = WeekDays.Monday, var version: Version = Version.Auto) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/settings/Version.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Version.kt similarity index 68% rename from src/commonMain/kotlin/com/ucasoft/kcron/settings/Version.kt rename to kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Version.kt index 0d305a1..5328b8b 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/settings/Version.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/settings/Version.kt @@ -1,4 +1,4 @@ -package com.ucasoft.kcron.settings +package com.ucasoft.kcron.core.settings enum class Version { diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/BuildAndParseTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/BuildAndParseTests.kt new file mode 100644 index 0000000..8234b27 --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/BuildAndParseTests.kt @@ -0,0 +1,69 @@ +package com.ucasoft.kcron.core + +import com.ucasoft.kcron.core.exceptions.WrongCronExpression +import com.ucasoft.kcron.kotlinx.datetime.CronLocalDateTimeProvider +import com.ucasoft.kcron.core.settings.Version +import io.kotest.assertions.throwables.shouldThrowWithMessage +import io.kotest.matchers.nulls.shouldNotBeNull +import io.kotest.matchers.shouldBe +import kotlin.test.BeforeTest +import kotlin.test.Test + +class BuildAndParseTests { + + private var currentYear : Int = 2024 + + private val modernCronExpression = "30 * * ? * * 2050" + + private val dateTimeProvider = CronLocalDateTimeProvider() + + @BeforeTest + fun setupOnce() { + currentYear = dateTimeProvider.now().year + } + + @Test + fun parseAndBuildAuto() { + var builder = Cron.parseAndBuild("* 12 ? * *", dateTimeProvider) + builder.expression.shouldBe("0 * 12 ? * * *") + builder.nextRun.shouldNotBeNull() + .year.shouldBe(currentYear) + builder = Cron.parseAndBuild(modernCronExpression, dateTimeProvider) + builder.expression.shouldBe(modernCronExpression) + builder.nextRun.shouldNotBeNull() + .year.shouldBe(2050) + shouldThrowWithMessage("Expression * * * ? * * is not Cron one!") { + Cron.parseAndBuild("* * * ? * *", dateTimeProvider) + } + } + + @Test + fun parseAndBuildClassic() { + val builder = Cron.parseAndBuild("* 12 ? * *", dateTimeProvider) { + it.version = Version.Classic + } + builder.expression.shouldBe("0 * 12 ? * * *") + builder.nextRun.shouldNotBeNull() + .year.shouldBe(currentYear) + shouldThrowWithMessage("Expression * * * ? * * * is not Classic Cron one!") { + Cron.parseAndBuild("* * * ? * * *", dateTimeProvider) { + it.version = Version.Classic + } + } + } + + @Test + fun parseAndBuildModern() { + val builder = Cron.parseAndBuild(modernCronExpression, dateTimeProvider) { + it.version = Version.Modern + } + builder.expression.shouldBe(modernCronExpression) + builder.nextRun.shouldNotBeNull() + .year.shouldBe(2050) + shouldThrowWithMessage("Expression * * ? * * is not Modern Cron one!") { + Cron.parseAndBuild("* * ? * *", dateTimeProvider) { + it.version = Version.Modern + } + } + } +} \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/BuilderTests.kt similarity index 88% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/BuilderTests.kt index 80a39f0..6f4ddf3 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/BuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/BuilderTests.kt @@ -1,8 +1,11 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.DayOfWeekGroups -import com.ucasoft.kcron.common.WeekDays -import com.ucasoft.kcron.extensions.* +import com.ucasoft.kcron.core.common.DayOfWeekGroups +import com.ucasoft.kcron.core.common.WeekDays +import com.ucasoft.kcron.core.extensions.* +import com.ucasoft.kcron.kotlinx.datetime.CronLocalDateTimeProvider +import com.ucasoft.kcron.kotlinx.datetime.plusDays +import com.ucasoft.kcron.kotlinx.datetime.plusHours import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldBeSingleton import io.kotest.matchers.collections.shouldHaveElementAt @@ -16,9 +19,11 @@ import kotlin.test.Test @OptIn(DelicateIterableApi::class) class BuilderTests { + private val dateTimeProvider = CronLocalDateTimeProvider() + @Test fun buildMany() { - val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()) + val builder = Builder(dateTimeProvider) builder.expression.shouldBe("* * * ? * * *") builder.days(1) builder.expression.shouldBe("* * * 1 * ? *") @@ -81,7 +86,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsSunday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Sunday, CronLocalDateTimeProvider()) + val builder = Builder(dateTimeProvider, WeekDays.Sunday) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -109,7 +114,7 @@ class BuilderTests { @Test fun buildManyFirstWeekDayIsWednesday() { val expected = LocalDateTime(2099, 1, 1, 0, 0) - val builder = Builder(WeekDays.Wednesday, CronLocalDateTimeProvider()) + val builder = Builder(dateTimeProvider, WeekDays.Wednesday) builder.years(2099).months(2).daysOfWeek(DayOfWeekGroups.EveryStartingAt, "6/1") var result = builder.asIterable().take(1) result.shouldBeSingleton { @@ -137,7 +142,7 @@ class BuilderTests { @Test fun iterableShouldStartFromStartDateTimeWhenItInSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2060 00:00:00 val start = LocalDate(2060, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2060 12:00:00 @@ -150,7 +155,7 @@ class BuilderTests { @Test fun iterableShouldStartFromFirstDatetimeDefinedByCronWhenStartDateTimeIsBeforeSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2010 00:00:00 val start = LocalDate(2010, 1, 1).atTime(0, 0, 0) // expect first run in 1 Jan 2050 12:00:00 (as defined in cron) @@ -163,7 +168,7 @@ class BuilderTests { @Test fun iterableShouldBeEmptyWhenStartDateTimeIsAfterSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2080 00:00:00 val start = LocalDate(2080, 1, 1).atTime(0, 0, 0) @@ -175,7 +180,7 @@ class BuilderTests { @Test fun iterableShouldBeFiniteForCronWithSpecifiedRange() { // setup cron to run every day at 12:00:00 from 2050 to 2070 - val builder = Builder(dateTimeProvider = CronLocalDateTimeProvider()).years(2050..2070).hours(12).minutes(0).seconds(0) + val builder = Builder(dateTimeProvider).years(2050..2070).hours(12).minutes(0).seconds(0) // set start datetime for iterable to 1 Jan 2070 00:00:00 val start = LocalDate(2070, 1, 1).atTime(0, 0, 0) // set expected runs count to be exactly 365 (once per day) diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysBuilderTests.kt similarity index 90% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysBuilderTests.kt index 35e8312..7d6c0d3 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysBuilderTests.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.DayGroups -import com.ucasoft.kcron.exceptions.UnknownCronPart +import com.ucasoft.kcron.core.common.DayGroups +import com.ucasoft.kcron.core.exceptions.UnknownCronPart import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.collections.shouldBeSingleton import io.kotest.matchers.collections.shouldContainExactly diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilderTests.kt similarity index 90% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilderTests.kt index 45b996b..5771a34 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/DaysOfWeekBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/DaysOfWeekBuilderTests.kt @@ -1,8 +1,8 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.DayOfWeekGroups -import com.ucasoft.kcron.common.WeekDays -import com.ucasoft.kcron.exceptions.UnknownCronPart +import com.ucasoft.kcron.core.common.DayOfWeekGroups +import com.ucasoft.kcron.core.common.WeekDays +import com.ucasoft.kcron.core.exceptions.UnknownCronPart import io.kotest.assertions.throwables.shouldThrow import io.kotest.matchers.collections.shouldBeSingleton import io.kotest.matchers.collections.shouldContainExactly diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/HoursBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/HoursBuilderTests.kt similarity index 90% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/HoursBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/HoursBuilderTests.kt index 6f8a02e..b713063 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/HoursBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/HoursBuilderTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.TimeGroups import io.kotest.matchers.collections.shouldContainExactly import kotlin.test.BeforeTest import kotlin.test.Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/MinutesBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilderTests.kt similarity index 91% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/MinutesBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilderTests.kt index 92ff6e1..e7f345d 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/MinutesBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MinutesBuilderTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.TimeGroups import io.kotest.matchers.collections.shouldContainExactly import kotlin.test.BeforeTest import kotlin.test.Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/MonthsBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilderTests.kt similarity index 91% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/MonthsBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilderTests.kt index 1c09c2d..a7499f5 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/MonthsBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/MonthsBuilderTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.MonthGroups +import com.ucasoft.kcron.core.common.MonthGroups import io.kotest.matchers.collections.shouldContainExactly import kotlin.test.BeforeTest import kotlin.test.Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/SecondsBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilderTests.kt similarity index 91% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/SecondsBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilderTests.kt index 0e1f010..4dba6ac 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/SecondsBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/SecondsBuilderTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.TimeGroups import io.kotest.matchers.collections.shouldContainExactly import kotlin.test.BeforeTest import kotlin.test.Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/builders/YearsBuilderTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/YearsBuilderTests.kt similarity index 70% rename from src/commonTest/kotlin/com/ucasoft/kcron/builders/YearsBuilderTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/YearsBuilderTests.kt index b3037b7..d083477 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/builders/YearsBuilderTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/builders/YearsBuilderTests.kt @@ -1,25 +1,26 @@ -package com.ucasoft.kcron.builders +package com.ucasoft.kcron.core.builders -import com.ucasoft.kcron.common.YearGroups +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import com.ucasoft.kcron.core.common.YearGroups +import com.ucasoft.kcron.kotlinx.datetime.CronLocalDateTimeProvider import io.kotest.matchers.collections.shouldContainExactly import io.kotest.matchers.collections.shouldEndWith import io.kotest.matchers.collections.shouldHaveElementAt -import kotlinx.datetime.Clock -import kotlinx.datetime.TimeZone -import kotlinx.datetime.toLocalDateTime import kotlin.test.BeforeTest import kotlin.test.Test class YearsBuilderTests { - private lateinit var builder : YearsBuilder + private val dateTimeProvider = CronLocalDateTimeProvider() + + private lateinit var builder : YearsBuilder> private var currentYear : Int = 2020 @BeforeTest fun setupOnce() { - builder = YearsBuilder() - currentYear = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()).year + builder = YearsBuilder(dateTimeProvider) + currentYear = dateTimeProvider.now().year } @Test diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayOfWeekValueGroup.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayOfWeekValueGroup.kt new file mode 100644 index 0000000..6f5be22 --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayOfWeekValueGroup.kt @@ -0,0 +1,5 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.DayOfWeekGroups + +class DayOfWeekValueGroup(val value: String, val group: DayOfWeekGroups) \ No newline at end of file diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayValueGroup.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayValueGroup.kt new file mode 100644 index 0000000..3d9b3a4 --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DayValueGroup.kt @@ -0,0 +1,5 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.DayGroups + +class DayValueGroup(val value: String, val group: DayGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekPartTests.kt similarity index 96% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekPartTests.kt index debe06b..d4e60fa 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysOfWeekPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysOfWeekPartTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.DayOfWeekGroups +import com.ucasoft.kcron.core.common.DayOfWeekGroups import io.kotest.assertions.withClue import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysPartTests.kt similarity index 96% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysPartTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysPartTests.kt index 0767bed..d67eca6 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DaysPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/DaysPartTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.DayGroups +import com.ucasoft.kcron.core.common.DayGroups import io.kotest.assertions.withClue import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/HoursPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/HoursPartTests.kt similarity index 95% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/HoursPartTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/HoursPartTests.kt index d533107..b94a3b7 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/HoursPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/HoursPartTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.TimeGroups import io.kotest.assertions.withClue import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt new file mode 100644 index 0000000..d92d71a --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt @@ -0,0 +1,75 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.MonthGroups +import io.kotest.assertions.withClue +import io.kotest.matchers.booleans.shouldBeFalse +import io.kotest.matchers.booleans.shouldBeTrue +import io.kotest.matchers.shouldBe +import kotlin.test.* + +class MonthPartTests { + + private lateinit var parser: MonthsParser + + private val allowedValues = listOf( + com.ucasoft.kcron.core.parsers.MonthValueGroup("*", MonthGroups.Any), + com.ucasoft.kcron.core.parsers.MonthValueGroup("1", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("6", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("12", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("JAN", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("JUN", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("DEC", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("1,12", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("JAN,DEC", MonthGroups.Specific), + com.ucasoft.kcron.core.parsers.MonthValueGroup("1-12", MonthGroups.EveryBetween), + com.ucasoft.kcron.core.parsers.MonthValueGroup("6-8", MonthGroups.EveryBetween), + com.ucasoft.kcron.core.parsers.MonthValueGroup("1/1", MonthGroups.EveryStartingAt), + com.ucasoft.kcron.core.parsers.MonthValueGroup("9/6", MonthGroups.EveryStartingAt), + com.ucasoft.kcron.core.parsers.MonthValueGroup("12/12", MonthGroups.EveryStartingAt) + ) + + private val deniedValues = listOf( + "**", + "0", + "13", + "6,", + ",12", + "1,13", + "1,10,13", + "JUC", + "JUC,DEC", + "JUN,DAY", + "1-", + "-12", + "10-13", + "0/12", + "1/13", + "13/12" + ) + + @BeforeTest + fun setupOnce() { + parser = MonthsParser() + } + + @Test + fun allowedValues() { + for (value in allowedValues) { + parser.parse(value.value) + parser.parse(value.value) + withClue(value.value) { + parser.isValid.shouldBeTrue() + } + parser.group.shouldBe(value.group) + } + } + + @Test + fun deniedValues() { + for (value in deniedValues) { + parser.parse(value) + parser.isValid.shouldBeFalse() + parser.group.shouldBe(MonthGroups.Unknown) + } + } +} \ No newline at end of file diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthValueGroup.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthValueGroup.kt new file mode 100644 index 0000000..f7761ea --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthValueGroup.kt @@ -0,0 +1,5 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.MonthGroups + +class MonthValueGroup(val value: String, val group: MonthGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt similarity index 59% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt index b107ce5..f7513c0 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/ParserTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt @@ -1,10 +1,9 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.exceptions.WrongCronExpression -import com.ucasoft.kcron.exceptions.WrongPartCombinations -import com.ucasoft.kcron.exceptions.WrongPartExpression -import com.ucasoft.kcron.exceptions.WrongPartsExpression -import com.ucasoft.kcron.settings.Version +import com.ucasoft.kcron.core.exceptions.WrongCronExpression +import com.ucasoft.kcron.core.exceptions.WrongPartCombinations +import com.ucasoft.kcron.core.exceptions.WrongPartExpression +import com.ucasoft.kcron.core.exceptions.WrongPartsExpression import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrowWithMessage import kotlin.test.Test @@ -27,18 +26,18 @@ class ParserTests { @Test fun goodClassicExpressions() { - parser.parse(allAnyClassicCronExpression, Version.Classic) - parser.parse("* * 29 * ?", Version.Classic) - parser.parse("* * ? * 1L", Version.Classic) - parser.parse("* * ? * MON/1", Version.Classic) + parser.parse(allAnyClassicCronExpression, com.ucasoft.kcron.core.settings.Version.Classic) + parser.parse("* * 29 * ?", com.ucasoft.kcron.core.settings.Version.Classic) + parser.parse("* * ? * 1L", com.ucasoft.kcron.core.settings.Version.Classic) + parser.parse("* * ? * MON/1", com.ucasoft.kcron.core.settings.Version.Classic) } @Test fun goodModernExpressions() { - parser.parse(allAnyModernCronExpression, Version.Modern) - parser.parse("* * * 29 * ? *", Version.Modern) - parser.parse("* * * ? * 1L *", Version.Modern) - parser.parse("* * * ? * MON/1 *", Version.Modern) + parser.parse(allAnyModernCronExpression, com.ucasoft.kcron.core.settings.Version.Modern) + parser.parse("* * * 29 * ? *", com.ucasoft.kcron.core.settings.Version.Modern) + parser.parse("* * * ? * 1L *", com.ucasoft.kcron.core.settings.Version.Modern) + parser.parse("* * * ? * MON/1 *", com.ucasoft.kcron.core.settings.Version.Modern) } @Test @@ -49,14 +48,14 @@ class ParserTests { @Test fun badClassicExpressions() { - shouldThrow { parser.parse("* * ? * * *", Version.Classic) } - shouldThrowWithMessage("Expression $allAnyModernCronExpression is not Classic Cron one!") { parser.parse(allAnyModernCronExpression, Version.Classic) } + shouldThrow { parser.parse("* * ? * * *", com.ucasoft.kcron.core.settings.Version.Classic) } + shouldThrowWithMessage("Expression $allAnyModernCronExpression is not Classic Cron one!") { parser.parse(allAnyModernCronExpression, com.ucasoft.kcron.core.settings.Version.Classic) } } @Test fun badModernExpressions() { - shouldThrow { parser.parse(allAnyClassicCronExpression, Version.Modern) } - shouldThrowWithMessage("Expression * * * ? ? * * * is not Modern Cron one!") { parser.parse("* * * ? ? * * *", Version.Modern) } + shouldThrow { parser.parse(allAnyClassicCronExpression, com.ucasoft.kcron.core.settings.Version.Modern) } + shouldThrowWithMessage("Expression * * * ? ? * * * is not Modern Cron one!") { parser.parse("* * * ? ? * * *", com.ucasoft.kcron.core.settings.Version.Modern) } } @Test diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/SecondsPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/SecondsPartTests.kt similarity index 93% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/SecondsPartTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/SecondsPartTests.kt index 8af9729..7603d7e 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/SecondsPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/SecondsPartTests.kt @@ -1,7 +1,7 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.TimeGroups +import com.ucasoft.kcron.core.common.CronPart +import com.ucasoft.kcron.core.common.TimeGroups import io.kotest.assertions.withClue import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/TimeValueGroup.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/TimeValueGroup.kt new file mode 100644 index 0000000..30ac1a5 --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/TimeValueGroup.kt @@ -0,0 +1,5 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.TimeGroups + +class TimeValueGroup(val value: String, val group: TimeGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt similarity index 89% rename from src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearPartTests.kt rename to kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt index a773057..236d84f 100644 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt @@ -1,6 +1,6 @@ -package com.ucasoft.kcron.parsers +package com.ucasoft.kcron.core.parsers -import com.ucasoft.kcron.common.YearGroups +import com.ucasoft.kcron.core.common.YearGroups import io.kotest.assertions.withClue import io.kotest.matchers.booleans.shouldBeFalse import io.kotest.matchers.booleans.shouldBeTrue @@ -9,7 +9,7 @@ import kotlin.test.* class YearPartTests { - private lateinit var parser: YearsParser + private lateinit var parser: com.ucasoft.kcron.core.parsers.YearsParser private val allowedValues = listOf( YearValueGroup("*", YearGroups.Any), @@ -43,7 +43,7 @@ class YearPartTests { @BeforeTest fun setupOnce() { - parser = YearsParser() + parser = com.ucasoft.kcron.core.parsers.YearsParser() } @Test diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearValueGroup.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearValueGroup.kt new file mode 100644 index 0000000..57373da --- /dev/null +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearValueGroup.kt @@ -0,0 +1,5 @@ +package com.ucasoft.kcron.core.parsers + +import com.ucasoft.kcron.core.common.YearGroups + +class YearValueGroup(val value: String, val group: YearGroups) \ No newline at end of file diff --git a/kcron-kotlinx-datetime/build.gradle.kts b/kcron-kotlinx-datetime/build.gradle.kts new file mode 100644 index 0000000..a74a748 --- /dev/null +++ b/kcron-kotlinx-datetime/build.gradle.kts @@ -0,0 +1,37 @@ +plugins { + alias(libs.plugins.multiplatform) + id("publish") +} + +kotlin { + jvm { + compilations.all { + kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() + } + } + linuxX64() + linuxArm64() + mingwX64() + macosX64() + macosArm64() + js(IR) { + browser() + nodejs() + } + iosX64() + iosArm64() + iosSimulatorArm64() + sourceSets { + commonMain { + dependencies { + implementation(project(":kcron-abstractions")) + api(libs.kotlinx.datetime) + } + } + } +} + +libraryData { + name.set("KCron Kotlinx DateTime") + description.set("Kotlinx DateTime Provider for Kotlin Multiplatform Cron realization") +} \ No newline at end of file diff --git a/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTime.kt b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTime.kt new file mode 100644 index 0000000..7020f16 --- /dev/null +++ b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTime.kt @@ -0,0 +1,45 @@ +package com.ucasoft.kcron.kotlinx.datetime + +import com.ucasoft.kcron.abstractions.CronDateTime +import kotlinx.datetime.* + +class CronLocalDateTime: CronDateTime { + + + private val dateTime: LocalDateTime + + constructor() { + dateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) + } + + constructor(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int) { + dateTime = LocalDateTime(year, month, day, hour, minute, second) + } + + override val year: Int + get() = dateTime.year + + override val month: Int + get() = dateTime.monthNumber + + override val dayOfMonth: Int + get() = dateTime.dayOfMonth + + override val isoDayOfWeek: Int + get() = dateTime.dayOfWeek.isoDayNumber + + override val hour: Int + get() = dateTime.hour + + override val minute: Int + get() = dateTime.minute + + override val second: Int + get() = dateTime.second + + override fun cast() = dateTime + + override fun plusDays(days: Int) = dateTime.plusDays(days).toCronLocalDateTime() + + override fun minusDays(days: Int) = dateTime.minusDays(days).toCronLocalDateTime() +} \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/LocalDateTime.kt b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeExtensions.kt similarity index 80% rename from src/commonMain/kotlin/com/ucasoft/kcron/extensions/LocalDateTime.kt rename to kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeExtensions.kt index 1fcef8d..6ba7c54 100644 --- a/src/commonMain/kotlin/com/ucasoft/kcron/extensions/LocalDateTime.kt +++ b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeExtensions.kt @@ -1,7 +1,10 @@ -package com.ucasoft.kcron.extensions +package com.ucasoft.kcron.kotlinx.datetime import kotlinx.datetime.* +fun LocalDateTime.toCronLocalDateTime() = + CronLocalDateTime(this.year, this.monthNumber, this.dayOfMonth, this.hour, this.minute, this.second) + fun LocalDateTime.plusHours(hours: Int, timeZone: TimeZone = TimeZone.currentSystemDefault()): LocalDateTime { return plus(this, hours, DateTimeUnit.HOUR, timeZone) } diff --git a/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeProvider.kt b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeProvider.kt new file mode 100644 index 0000000..f9f56dd --- /dev/null +++ b/kcron-kotlinx-datetime/src/commonMain/kotlin/com/ucasoft/kcron/kotlinx/datetime/CronLocalDateTimeProvider.kt @@ -0,0 +1,15 @@ +package com.ucasoft.kcron.kotlinx.datetime + +import com.ucasoft.kcron.abstractions.CronDateTimeProvider +import kotlinx.datetime.LocalDateTime + +class CronLocalDateTimeProvider : CronDateTimeProvider { + + override fun now() = CronLocalDateTime() + + override fun from(year: Int, month: Int, day: Int, hours: Int, minutes: Int, seconds: Int) = + CronLocalDateTime(year, month, day, hours, minutes, seconds) + + override fun from(original: LocalDateTime) = original.toCronLocalDateTime() + +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index f7386f7..cf3d077 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,12 @@ +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" +} -rootProject.name = "kcron-common" +rootProject.name = "kcron" + +include( + "kcron-abstractions", + "kcron-common", + "kcron-core", + "kcron-kotlinx-datetime" +) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt b/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt deleted file mode 100644 index 6428ce6..0000000 --- a/src/commonMain/kotlin/com/ucasoft/kcron/Cron.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.ucasoft.kcron - -import com.ucasoft.kcron.builders.Builder -import com.ucasoft.kcron.builders.CronDateTimeProvider -import com.ucasoft.kcron.builders.CronLocalDateTime -import com.ucasoft.kcron.builders.CronLocalDateTimeProvider -import com.ucasoft.kcron.common.WeekDays -import com.ucasoft.kcron.parsers.Parser -import com.ucasoft.kcron.settings.Settings -import kotlinx.datetime.LocalDateTime - -class Cron { - - companion object { - - fun parseAndBuild(expression: String, block: (Settings) -> Unit = {}) : Builder { - val settings = Settings() - block.invoke(settings) - val parseResult = Parser().parse(expression, settings.version) - return Builder(settings.firstDayOfWeek, CronLocalDateTimeProvider()).build(parseResult.parts) - } - - fun builder(firstDayOfWeek: WeekDays = WeekDays.Monday): Builder { - return Builder(firstDayOfWeek, CronLocalDateTimeProvider()) - } - } -} - -@Deprecated( - message = "Class name should not explicitly tell it's written in Kotlin (with starting 'K'). It would be compiled in Java bytecode, Javascript, etc.", - replaceWith = ReplaceWith("Cron") -) -typealias KCron = Cron diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt b/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt deleted file mode 100644 index a30252f..0000000 --- a/src/commonMain/kotlin/com/ucasoft/kcron/builders/CronDateTime.kt +++ /dev/null @@ -1,105 +0,0 @@ -package com.ucasoft.kcron.builders - -import com.ucasoft.kcron.extensions.minusDays -import com.ucasoft.kcron.extensions.plusDays -import kotlinx.datetime.* - -interface CronDateTime { - - val year: Int - - val month: Int - - val dayOfMonth: Int - - val isoDayOfWeek: Int - - val hour: Int - - val minute: Int - - val second: Int - - fun cast() : T - - fun plusDays(days: Int): CronDateTime - - fun minusDays(days: Int): CronDateTime -} - -interface CronDateTimeProvider where D: CronDateTime { - - fun now(): D - - fun from( - year: Int, - month: Int, - day: Int, - hours: Int = 0, - minutes: Int = 0, - seconds: Int = 0 - ): D - - fun from(original: T) : D -} - -class CronLocalDateTime: CronDateTime { - - - private val dateTime: LocalDateTime - - constructor() { - dateTime = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) - } - - constructor(year: Int, - month: Int, - day: Int, - hour: Int, - minute: Int, - second: Int) { - dateTime = LocalDateTime(year, month, day, hour, minute, second) - } - - override val year: Int - get() = dateTime.year - - override val month: Int - get() = dateTime.monthNumber - - override val dayOfMonth: Int - get() = dateTime.dayOfMonth - override val isoDayOfWeek: Int - get() = dateTime.dayOfWeek.isoDayNumber - override val hour: Int - get() = dateTime.hour - override val minute: Int - get() = dateTime.minute - override val second: Int - get() = dateTime.second - - override fun cast() = dateTime - - override fun plusDays(days: Int) = dateTime.plusDays(days).toCronLocalDateTime() - - override fun minusDays(days: Int) = dateTime.minusDays(days).toCronLocalDateTime() -} - -class CronLocalDateTimeProvider : CronDateTimeProvider { - - override fun now() = CronLocalDateTime() - - override fun from( - year: Int, - month: Int, - day: Int, - hours: Int, - minutes: Int, - seconds: Int - ) = CronLocalDateTime(year, month, day, hours, minutes, seconds) - - override fun from(original: LocalDateTime) = original.toCronLocalDateTime() - -} - -fun LocalDateTime.toCronLocalDateTime() = CronLocalDateTime(this.year, this.monthNumber, this.dayOfMonth, this.hour, this.minute, this.second) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/CombinationRule.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/CombinationRule.kt deleted file mode 100644 index aec59f0..0000000 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/CombinationRule.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.CronGroups -import com.ucasoft.kcron.common.CronPart - -class CombinationRule(val part: CronPart, val type: CronGroups, val dependencies: List? = null) \ No newline at end of file diff --git a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/ParseResult.kt b/src/commonMain/kotlin/com/ucasoft/kcron/parsers/ParseResult.kt deleted file mode 100644 index ee8391d..0000000 --- a/src/commonMain/kotlin/com/ucasoft/kcron/parsers/ParseResult.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.CronPart -import com.ucasoft.kcron.common.PartValue - -class ParseResult { - - val parts = mutableMapOf() -} \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayOfWeekValueGroup.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayOfWeekValueGroup.kt deleted file mode 100644 index 2710eb1..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayOfWeekValueGroup.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.DayOfWeekGroups - -class DayOfWeekValueGroup(val value: String, val group: DayOfWeekGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayValueGroup.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayValueGroup.kt deleted file mode 100644 index 7636d63..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/DayValueGroup.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.DayGroups - -class DayValueGroup(val value: String, val group: DayGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthPartTests.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthPartTests.kt deleted file mode 100644 index 752ef21..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthPartTests.kt +++ /dev/null @@ -1,75 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.MonthGroups -import io.kotest.assertions.withClue -import io.kotest.matchers.booleans.shouldBeFalse -import io.kotest.matchers.booleans.shouldBeTrue -import io.kotest.matchers.shouldBe -import kotlin.test.* - -class MonthPartTests { - - private lateinit var parser: MonthsParser - - private val allowedValues = listOf( - MonthValueGroup("*", MonthGroups.Any), - MonthValueGroup("1", MonthGroups.Specific), - MonthValueGroup("6", MonthGroups.Specific), - MonthValueGroup("12", MonthGroups.Specific), - MonthValueGroup("JAN", MonthGroups.Specific), - MonthValueGroup("JUN", MonthGroups.Specific), - MonthValueGroup("DEC", MonthGroups.Specific), - MonthValueGroup("1,12", MonthGroups.Specific), - MonthValueGroup("JAN,DEC", MonthGroups.Specific), - MonthValueGroup("1-12", MonthGroups.EveryBetween), - MonthValueGroup("6-8", MonthGroups.EveryBetween), - MonthValueGroup("1/1", MonthGroups.EveryStartingAt), - MonthValueGroup("9/6", MonthGroups.EveryStartingAt), - MonthValueGroup("12/12", MonthGroups.EveryStartingAt) - ) - - private val deniedValues = listOf( - "**", - "0", - "13", - "6,", - ",12", - "1,13", - "1,10,13", - "JUC", - "JUC,DEC", - "JUN,DAY", - "1-", - "-12", - "10-13", - "0/12", - "1/13", - "13/12" - ) - - @BeforeTest - fun setupOnce() { - parser = MonthsParser() - } - - @Test - fun allowedValues() { - for (value in allowedValues) { - parser.parse(value.value) - parser.parse(value.value) - withClue(value.value) { - parser.isValid.shouldBeTrue() - } - parser.group.shouldBe(value.group) - } - } - - @Test - fun deniedValues() { - for (value in deniedValues) { - parser.parse(value) - parser.isValid.shouldBeFalse() - parser.group.shouldBe(MonthGroups.Unknown) - } - } -} \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthValueGroup.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthValueGroup.kt deleted file mode 100644 index 8abcd53..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/MonthValueGroup.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.MonthGroups - -class MonthValueGroup(val value: String, val group: MonthGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/TimeValueGroup.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/TimeValueGroup.kt deleted file mode 100644 index 95719fc..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/TimeValueGroup.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.TimeGroups - -class TimeValueGroup(val value: String, val group: TimeGroups) \ No newline at end of file diff --git a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearValueGroup.kt b/src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearValueGroup.kt deleted file mode 100644 index 808e0f8..0000000 --- a/src/commonTest/kotlin/com/ucasoft/kcron/parsers/YearValueGroup.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.ucasoft.kcron.parsers - -import com.ucasoft.kcron.common.YearGroups - -class YearValueGroup(val value: String, val group: YearGroups) \ No newline at end of file From 8e23a0e54feada9b338f9419fd7dae5dcf7e767d Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 22 Jan 2024 15:28:43 +0100 Subject: [PATCH 4/6] Update README --- README.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ad36c05..d54d837 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# KCron Common +# KCron 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.9.2?color=blue)](https://search.maven.org/artifact/com.ucasoft.kcron/kcron-common/0.9.2/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.10.0?color=blue)](https://search.maven.org/artifact/com.ucasoft.kcron/kcron-common/0.10.0/jar) ### Features * Kotlin Multiplatform library @@ -31,14 +31,16 @@ builder * macOS * Javascript * iOS +* Support different DateTime libraries (via DateTime Provider Abstractions) ### Usage +#### KCron-Common library as default implementation uses [Kotlinx-DateTime](https://github.com/Kotlin/kotlinx-datetime) library ***Add with Gradle*** ```groovy kotlin { sourceSets { commonMain { dependencies { - implementation 'com.ucasoft.kcron:kcron-common:0.9.2' + implementation 'com.ucasoft.kcron:kcron-common:0.10.0' } } } @@ -103,6 +105,6 @@ builder.years(2021..2025) println(builder.expression) // 0/10 5-25 5,12 ? * SUN#5 2021-2025 ``` ### Current status -This library is on beta version `0.9.2`. -However, it will be a part of another cool library. -Check the news! +This library is on beta version `0.10.0`. +It is continuing to develop. +Check the news! From abeaca307e40748af2c0cadb4ccf47c75446458c Mon Sep 17 00:00:00 2001 From: Sergey Date: Mon, 22 Jan 2024 15:28:53 +0100 Subject: [PATCH 5/6] Fix tests --- build.gradle.kts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 6292eb0..c9cf379 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,4 +7,10 @@ allprojects { repositories { mavenCentral() } + + tasks.withType { + reports { + junitXml.required.set(true) + } + } } \ No newline at end of file From 1c9bd79dfef302099384bb09796510b419c476f4 Mon Sep 17 00:00:00 2001 From: Sergey Antonov Date: Wed, 24 Jan 2024 10:16:23 +0100 Subject: [PATCH 6/6] Fix PR comments --- .../ucasoft/kcron/core/builders/Builder.kt | 18 ++++-------- .../kcron/core/parsers/CombinationRule.kt | 2 +- .../com/ucasoft/kcron/core/parsers/Parser.kt | 10 ++----- .../kcron/core/parsers/MonthPartTests.kt | 28 +++++++++---------- .../ucasoft/kcron/core/parsers/ParserTests.kt | 25 +++++++++-------- .../kcron/core/parsers/YearPartTests.kt | 4 +-- 6 files changed, 38 insertions(+), 49 deletions(-) diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt index 97a8a64..3902bd5 100644 --- a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/builders/Builder.kt @@ -35,24 +35,20 @@ class Builder, P: CronDateTimeProvider>(private val private val firstDayOfWeekIndex = WeekDays.entries.indexOf(firstDayOfWeek) - fun build(parts: Map): Builder { + fun build(parts: Map) = apply { parts.forEach { entry -> partBuilders[entry.key]?.commonBuild(entry.value.type, entry.value.value) } - return this } - fun seconds(type: TimeGroups, value: String) : Builder { + fun seconds(type: TimeGroups, value: String) = apply { partBuilders.getValue(CronPart.Seconds).commonBuild(type, value) - return this } - fun minutes(type: TimeGroups, value: String) : Builder { + fun minutes(type: TimeGroups, value: String) = apply { partBuilders.getValue(CronPart.Minutes).commonBuild(type, value) - return this } - fun hours(type: TimeGroups, value: String) : Builder { + fun hours(type: TimeGroups, value: String) = apply { partBuilders.getValue(CronPart.Hours).commonBuild(type, value) - return this } fun days(type: DayGroups, value: String) : Builder { @@ -65,9 +61,8 @@ class Builder, P: CronDateTimeProvider>(private val return this } - fun months(type: MonthGroups, value: String) : Builder { + fun months(type: MonthGroups, value: String) = apply { partBuilders.getValue(CronPart.Months).commonBuild(type, value) - return this } fun daysOfWeek(type: DayOfWeekGroups, value: String) : Builder { @@ -78,9 +73,8 @@ class Builder, P: CronDateTimeProvider>(private val return this } - fun years(type: YearGroups, value: String) : Builder { + fun years(type: YearGroups, value: String) = apply { partBuilders.getValue(CronPart.Years).commonBuild(type, value) - return this } @DelicateIterableApi diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt index dc8519d..a232a36 100644 --- a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/CombinationRule.kt @@ -3,4 +3,4 @@ package com.ucasoft.kcron.core.parsers import com.ucasoft.kcron.core.common.CronGroups import com.ucasoft.kcron.core.common.CronPart -class CombinationRule(val part: CronPart, val type: CronGroups, val dependencies: List? = null) \ No newline at end of file +class CombinationRule(val part: CronPart, val type: CronGroups, val dependencies: List = emptyList()) \ No newline at end of file diff --git a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt index 25b8485..9772a77 100644 --- a/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt +++ b/kcron-core/src/commonMain/kotlin/com/ucasoft/kcron/core/parsers/Parser.kt @@ -82,16 +82,10 @@ class Parser { for (part in parts) { val rule = combinationRules.firstOrNull { r -> r.part == part.key && r.type == part.value.type } if (rule != null) { - for (dependency in rule.dependencies!!) { + for (dependency in rule.dependencies) { val secondPart = parts[dependency.part] if (secondPart!!.type != dependency.type) { - combinationExceptions.add( - WrongPartCombination( - part, - dependency, - secondPart - ) - ) + combinationExceptions.add(WrongPartCombination(part, dependency, secondPart)) } } } diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt index d92d71a..659a0bb 100644 --- a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/MonthPartTests.kt @@ -12,20 +12,20 @@ class MonthPartTests { private lateinit var parser: MonthsParser private val allowedValues = listOf( - com.ucasoft.kcron.core.parsers.MonthValueGroup("*", MonthGroups.Any), - com.ucasoft.kcron.core.parsers.MonthValueGroup("1", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("6", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("12", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("JAN", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("JUN", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("DEC", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("1,12", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("JAN,DEC", MonthGroups.Specific), - com.ucasoft.kcron.core.parsers.MonthValueGroup("1-12", MonthGroups.EveryBetween), - com.ucasoft.kcron.core.parsers.MonthValueGroup("6-8", MonthGroups.EveryBetween), - com.ucasoft.kcron.core.parsers.MonthValueGroup("1/1", MonthGroups.EveryStartingAt), - com.ucasoft.kcron.core.parsers.MonthValueGroup("9/6", MonthGroups.EveryStartingAt), - com.ucasoft.kcron.core.parsers.MonthValueGroup("12/12", MonthGroups.EveryStartingAt) + MonthValueGroup("*", MonthGroups.Any), + MonthValueGroup("1", MonthGroups.Specific), + MonthValueGroup("6", MonthGroups.Specific), + MonthValueGroup("12", MonthGroups.Specific), + MonthValueGroup("JAN", MonthGroups.Specific), + MonthValueGroup("JUN", MonthGroups.Specific), + MonthValueGroup("DEC", MonthGroups.Specific), + MonthValueGroup("1,12", MonthGroups.Specific), + MonthValueGroup("JAN,DEC", MonthGroups.Specific), + MonthValueGroup("1-12", MonthGroups.EveryBetween), + MonthValueGroup("6-8", MonthGroups.EveryBetween), + MonthValueGroup("1/1", MonthGroups.EveryStartingAt), + MonthValueGroup("9/6", MonthGroups.EveryStartingAt), + MonthValueGroup("12/12", MonthGroups.EveryStartingAt) ) private val deniedValues = listOf( diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt index f7513c0..df1553f 100644 --- a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/ParserTests.kt @@ -4,6 +4,7 @@ import com.ucasoft.kcron.core.exceptions.WrongCronExpression import com.ucasoft.kcron.core.exceptions.WrongPartCombinations import com.ucasoft.kcron.core.exceptions.WrongPartExpression import com.ucasoft.kcron.core.exceptions.WrongPartsExpression +import com.ucasoft.kcron.core.settings.Version import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.throwables.shouldThrowWithMessage import kotlin.test.Test @@ -26,18 +27,18 @@ class ParserTests { @Test fun goodClassicExpressions() { - parser.parse(allAnyClassicCronExpression, com.ucasoft.kcron.core.settings.Version.Classic) - parser.parse("* * 29 * ?", com.ucasoft.kcron.core.settings.Version.Classic) - parser.parse("* * ? * 1L", com.ucasoft.kcron.core.settings.Version.Classic) - parser.parse("* * ? * MON/1", com.ucasoft.kcron.core.settings.Version.Classic) + parser.parse(allAnyClassicCronExpression, Version.Classic) + parser.parse("* * 29 * ?", Version.Classic) + parser.parse("* * ? * 1L", Version.Classic) + parser.parse("* * ? * MON/1", Version.Classic) } @Test fun goodModernExpressions() { - parser.parse(allAnyModernCronExpression, com.ucasoft.kcron.core.settings.Version.Modern) - parser.parse("* * * 29 * ? *", com.ucasoft.kcron.core.settings.Version.Modern) - parser.parse("* * * ? * 1L *", com.ucasoft.kcron.core.settings.Version.Modern) - parser.parse("* * * ? * MON/1 *", com.ucasoft.kcron.core.settings.Version.Modern) + parser.parse(allAnyModernCronExpression, Version.Modern) + parser.parse("* * * 29 * ? *", Version.Modern) + parser.parse("* * * ? * 1L *", Version.Modern) + parser.parse("* * * ? * MON/1 *", Version.Modern) } @Test @@ -48,14 +49,14 @@ class ParserTests { @Test fun badClassicExpressions() { - shouldThrow { parser.parse("* * ? * * *", com.ucasoft.kcron.core.settings.Version.Classic) } - shouldThrowWithMessage("Expression $allAnyModernCronExpression is not Classic Cron one!") { parser.parse(allAnyModernCronExpression, com.ucasoft.kcron.core.settings.Version.Classic) } + shouldThrow { parser.parse("* * ? * * *", Version.Classic) } + shouldThrowWithMessage("Expression $allAnyModernCronExpression is not Classic Cron one!") { parser.parse(allAnyModernCronExpression, Version.Classic) } } @Test fun badModernExpressions() { - shouldThrow { parser.parse(allAnyClassicCronExpression, com.ucasoft.kcron.core.settings.Version.Modern) } - shouldThrowWithMessage("Expression * * * ? ? * * * is not Modern Cron one!") { parser.parse("* * * ? ? * * *", com.ucasoft.kcron.core.settings.Version.Modern) } + shouldThrow { parser.parse(allAnyClassicCronExpression, Version.Modern) } + shouldThrowWithMessage("Expression * * * ? ? * * * is not Modern Cron one!") { parser.parse("* * * ? ? * * *", Version.Modern) } } @Test diff --git a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt index 236d84f..530432a 100644 --- a/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt +++ b/kcron-core/src/commonTest/kotlin/com/ucasoft/kcron/core/parsers/YearPartTests.kt @@ -9,7 +9,7 @@ import kotlin.test.* class YearPartTests { - private lateinit var parser: com.ucasoft.kcron.core.parsers.YearsParser + private lateinit var parser: YearsParser private val allowedValues = listOf( YearValueGroup("*", YearGroups.Any), @@ -43,7 +43,7 @@ class YearPartTests { @BeforeTest fun setupOnce() { - parser = com.ucasoft.kcron.core.parsers.YearsParser() + parser = YearsParser() } @Test