From 3083fe2218c4cd8cb289306a57d334e5cbec0bfe Mon Sep 17 00:00:00 2001 From: Sasikanth Miriyampalli Date: Sat, 6 Jan 2024 07:27:12 +0530 Subject: [PATCH] Lock clock when testing date time formatters This is done to fix the failing date formatters test. The reason it fails is, since one of the date format we have doesn't have year attached to it "MM-dd HH:mm:ss", it picks it from the current system time. The expected value I provided was for year 2023, but since the year is now 2024, the tests has started to fail. So locking the clock (which I should've done from the start) to a specific date time, so that the tests are reproducible. --- .../parser/DateTimeFormatters.android.kt | 10 +++-- .../core/network/parser/DateTimeFormatters.kt | 4 +- .../network/parser/DateTimeFormattersTest.kt | 4 +- .../reader/core/network/parser/TestClock.kt | 38 +++++++++++++++++++ .../network/parser/DateTimeFormatters.ios.kt | 7 ++-- 5 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/TestClock.kt diff --git a/core/network/src/androidMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.android.kt b/core/network/src/androidMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.android.kt index 18880c255..8c5f374df 100644 --- a/core/network/src/androidMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.android.kt +++ b/core/network/src/androidMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.android.kt @@ -16,13 +16,15 @@ package dev.sasikanth.rss.reader.core.network.parser -import java.time.LocalDateTime import java.time.ZoneId import java.time.format.DateTimeFormatter import java.time.temporal.ChronoField import java.time.temporal.UnsupportedTemporalTypeException +import kotlinx.datetime.Clock import kotlinx.datetime.TimeZone +import kotlinx.datetime.toJavaLocalDateTime import kotlinx.datetime.toJavaZoneId +import kotlinx.datetime.toLocalDateTime private val dateFormatters = listOf( @@ -45,13 +47,15 @@ private val dateFormatters = ) @Throws(DateTimeFormatException::class) -internal actual fun String?.dateStringToEpochMillis(): Long? { +internal actual fun String?.dateStringToEpochMillis(clock: Clock): Long? { if (this.isNullOrBlank()) return null + val currentDate = + clock.now().toLocalDateTime(TimeZone.currentSystemDefault()).toJavaLocalDateTime() + for (dateFormatter in dateFormatters) { try { val parsedValue = dateFormatter.parse(this) - val currentDate = LocalDateTime.now() val year = try { diff --git a/core/network/src/commonMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.kt b/core/network/src/commonMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.kt index dca7945df..77bdfef34 100644 --- a/core/network/src/commonMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.kt +++ b/core/network/src/commonMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.kt @@ -16,6 +16,8 @@ package dev.sasikanth.rss.reader.core.network.parser -internal expect fun String?.dateStringToEpochMillis(): Long? +import kotlinx.datetime.Clock + +internal expect fun String?.dateStringToEpochMillis(clock: Clock = Clock.System): Long? data class DateTimeFormatException(val exception: Exception) : Exception() diff --git a/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormattersTest.kt b/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormattersTest.kt index 9062c644d..1528e5ede 100644 --- a/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormattersTest.kt +++ b/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormattersTest.kt @@ -72,7 +72,7 @@ class DateTimeFormattersTest { val epochMillis = dates.map { try { - it.dateStringToEpochMillis() + it.dateStringToEpochMillis(clock = TestClock) } catch (e: Exception) { // no-op } @@ -88,7 +88,7 @@ class DateTimeFormattersTest { val invalidDate = "Invalid date" // when - val epochMillis = invalidDate.dateStringToEpochMillis() + val epochMillis = invalidDate.dateStringToEpochMillis(clock = TestClock) // then assertEquals(null, epochMillis) diff --git a/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/TestClock.kt b/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/TestClock.kt new file mode 100644 index 000000000..96e82e495 --- /dev/null +++ b/core/network/src/commonTest/kotlin/dev/sasikanth/rss/reader/core/network/parser/TestClock.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2024 Sasikanth Miriyampalli + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dev.sasikanth.rss.reader.core.network.parser + +import kotlinx.datetime.Clock +import kotlinx.datetime.Instant +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.Month +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toInstant + +object TestClock : Clock { + + override fun now(): Instant { + return LocalDateTime( + year = 2023, + month = Month.JANUARY, + dayOfMonth = 1, + hour = 8, + minute = 0, + ) + .toInstant(TimeZone.UTC) + } +} diff --git a/core/network/src/iosMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.ios.kt b/core/network/src/iosMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.ios.kt index 621882361..2807342d6 100644 --- a/core/network/src/iosMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.ios.kt +++ b/core/network/src/iosMain/kotlin/dev/sasikanth/rss/reader/core/network/parser/DateTimeFormatters.ios.kt @@ -16,7 +16,9 @@ package dev.sasikanth.rss.reader.core.network.parser +import kotlinx.datetime.Clock import kotlinx.datetime.TimeZone +import kotlinx.datetime.toNSDate import kotlinx.datetime.toNSTimeZone import platform.Foundation.NSCalendar import platform.Foundation.NSCalendarIdentifierGregorian @@ -27,7 +29,6 @@ import platform.Foundation.NSCalendarUnitMonth import platform.Foundation.NSCalendarUnitNanosecond import platform.Foundation.NSCalendarUnitSecond import platform.Foundation.NSCalendarUnitYear -import platform.Foundation.NSDate import platform.Foundation.NSDateFormatter import platform.Foundation.NSLocale import platform.Foundation.timeIntervalSince1970 @@ -68,7 +69,7 @@ private val dateFormatters = ) @Throws(DateTimeFormatException::class) -internal actual fun String?.dateStringToEpochMillis(): Long? { +internal actual fun String?.dateStringToEpochMillis(clock: Clock): Long? { if (this.isNullOrBlank()) return null try { @@ -78,7 +79,7 @@ internal actual fun String?.dateStringToEpochMillis(): Long? { } if (date != null) { - val currentDate = NSDate() + val currentDate = clock.now().toNSDate() val calendar = NSCalendar(NSCalendarIdentifierGregorian) val currentYear = calendar.component(NSCalendarUnitYear, currentDate)