Change Clock to kotlinx.datetime.Clock

This commit is contained in:
Wolf Montwé 2023-03-01 17:27:34 +01:00
parent 2ce7c6e412
commit 28e3f62a4e
No known key found for this signature in database
GPG key ID: 6D45B21512ACBF72
29 changed files with 93 additions and 73 deletions

View file

@ -27,6 +27,7 @@ dependencies {
implementation(libs.mime4j.core)
implementation(libs.mime4j.dom)
testApi(projects.core.testing)
testImplementation(projects.mail.testing)
testImplementation(projects.backend.imap)
testImplementation(projects.mail.protocols.smtp)

View file

@ -1,13 +0,0 @@
package com.fsck.k9
/**
* An interface to provide the current time.
*/
interface Clock {
val time: Long
}
internal class RealClock : Clock {
override val time: Long
get() = System.currentTimeMillis()
}

View file

@ -9,6 +9,7 @@ import com.fsck.k9.mailstore.LocalStore
import com.fsck.k9.preferences.RealGeneralSettingsManager
import com.fsck.k9.preferences.Storage
import com.fsck.k9.preferences.StorageEditor
import kotlinx.datetime.Clock
import timber.log.Timber
import timber.log.Timber.DebugTree

View file

@ -10,6 +10,7 @@ import com.fsck.k9.mailstore.LocalStoreProvider
import com.fsck.k9.setup.ServerNameSuggester
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.GlobalScope
import kotlinx.datetime.Clock
import org.koin.core.qualifier.named
import org.koin.dsl.module
@ -30,7 +31,7 @@ val mainModule = module {
single { TrustManagerFactory.createInstance(get()) }
single { LocalKeyStoreManager(get()) }
single<TrustedSocketFactory> { DefaultTrustedSocketFactory(get(), get()) }
single<Clock> { RealClock() }
single<Clock> { Clock.System }
factory { ServerNameSuggester() }
factory { EmailAddressValidator() }
factory { ServerSettingsSerializer() }

View file

@ -3,6 +3,8 @@ package com.fsck.k9;
import java.util.Calendar;
import kotlinx.datetime.Clock;
class QuietTimeChecker {
private final Clock clock;
@ -31,7 +33,7 @@ class QuietTimeChecker {
}
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(clock.getTime());
calendar.setTimeInMillis(clock.now().toEpochMilliseconds());
int minutesSinceMidnight = (calendar.get(Calendar.HOUR_OF_DAY) * 60) + calendar.get(Calendar.MINUTE);

View file

@ -1,11 +1,12 @@
package com.fsck.k9.cache
import com.fsck.k9.Clock
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
internal class ExpiringCache<KEY : Any, VALUE : Any>(
private val clock: Clock,
private val delegateCache: Cache<KEY, VALUE> = InMemoryCache(),
private var lastClearTime: Long = clock.time,
private var lastClearTime: Instant = clock.now(),
private val cacheTimeValidity: Long = CACHE_TIME_VALIDITY_IN_MILLIS,
) : Cache<KEY, VALUE> {
@ -25,7 +26,7 @@ internal class ExpiringCache<KEY : Any, VALUE : Any>(
}
override fun clear() {
lastClearTime = clock.time
lastClearTime = clock.now()
delegateCache.clear()
}
@ -36,7 +37,7 @@ internal class ExpiringCache<KEY : Any, VALUE : Any>(
}
private fun isExpired(): Boolean {
return (clock.time - lastClearTime) >= cacheTimeValidity
return (clock.now() - lastClearTime).inWholeMilliseconds >= cacheTimeValidity
}
private companion object {

View file

@ -8,12 +8,15 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.workDataOf
import com.fsck.k9.Account
import com.fsck.k9.Clock
import com.fsck.k9.K9
import java.util.concurrent.TimeUnit
import kotlinx.datetime.Clock
import timber.log.Timber
class MailSyncWorkerManager(private val workManager: WorkManager, val clock: Clock) {
class MailSyncWorkerManager(
private val workManager: WorkManager,
val clock: Clock,
) {
fun cancelMailSync(account: Account) {
Timber.v("Canceling mail sync worker for %s", account)
@ -66,7 +69,7 @@ class MailSyncWorkerManager(private val workManager: WorkManager, val clock: Clo
}
private fun calculateInitialDelay(lastSyncTime: Long, syncIntervalMinutes: Long): Long {
val now = clock.time
val now = clock.now().toEpochMilliseconds()
val nextSyncTime = lastSyncTime + (syncIntervalMinutes * 60L * 1000L)
return if (lastSyncTime > now || nextSyncTime <= now) {

View file

@ -27,7 +27,6 @@ import android.text.TextUtils;
import androidx.core.database.CursorKt;
import com.fsck.k9.Account;
import com.fsck.k9.Clock;
import com.fsck.k9.DI;
import com.fsck.k9.Preferences;
import com.fsck.k9.controller.MessagingControllerCommands.PendingCommand;
@ -52,6 +51,7 @@ import com.fsck.k9.search.LocalSearch;
import com.fsck.k9.search.SearchSpecification.Attribute;
import com.fsck.k9.search.SearchSpecification.SearchField;
import com.fsck.k9.search.SqlQueryBuilder;
import kotlinx.datetime.Clock;
import org.apache.commons.io.IOUtils;
import org.apache.james.mime4j.codec.Base64InputStream;
import org.apache.james.mime4j.codec.QuotedPrintableInputStream;

View file

@ -1,13 +1,16 @@
package com.fsck.k9.mailstore
import android.content.ContentValues
import com.fsck.k9.Clock
import com.fsck.k9.helper.getIntOrThrow
import com.fsck.k9.helper.getLongOrThrow
import com.fsck.k9.helper.getStringOrNull
import com.fsck.k9.helper.getStringOrThrow
import kotlinx.datetime.Clock
class OutboxStateRepository(private val database: LockableDatabase, private val clock: Clock) {
class OutboxStateRepository(
private val database: LockableDatabase,
private val clock: Clock,
) {
fun getOutboxState(messageId: Long): OutboxState {
return database.execute(false) { db ->
@ -76,7 +79,7 @@ class OutboxStateRepository(private val database: LockableDatabase, private val
}
fun setSendAttemptError(messageId: Long, errorMessage: String) {
val sendErrorTimestamp = clock.time
val sendErrorTimestamp = clock.now().toEpochMilliseconds()
database.execute(false) { db ->
val contentValues = ContentValues().apply {
@ -90,7 +93,7 @@ class OutboxStateRepository(private val database: LockableDatabase, private val
}
fun setSendAttemptsExceeded(messageId: Long) {
val sendErrorTimestamp = clock.time
val sendErrorTimestamp = clock.now().toEpochMilliseconds()
database.execute(false) { db ->
val contentValues = ContentValues().apply {

View file

@ -1,9 +1,9 @@
package com.fsck.k9.notification
import com.fsck.k9.Account
import com.fsck.k9.Clock
import com.fsck.k9.controller.MessageReference
import com.fsck.k9.mailstore.LocalMessage
import kotlinx.datetime.Clock
/**
* Manages notifications for new messages
@ -130,5 +130,5 @@ internal class NewMailNotificationManager(
}
}
private fun now(): Long = clock.time
private fun now(): Long = clock.now().toEpochMilliseconds()
}

View file

@ -18,7 +18,6 @@ import android.text.TextUtils;
import androidx.annotation.VisibleForTesting;
import com.fsck.k9.Account;
import com.fsck.k9.AccountPreferenceSerializer;
import com.fsck.k9.Clock;
import com.fsck.k9.Core;
import com.fsck.k9.DI;
import com.fsck.k9.Identity;
@ -30,6 +29,7 @@ import com.fsck.k9.mail.ConnectionSecurity;
import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mailstore.SpecialLocalFoldersCreator;
import com.fsck.k9.preferences.Settings.InvalidSettingValueException;
import kotlinx.datetime.Clock;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
@ -469,7 +469,7 @@ public class SettingsImporter {
// To avoid reusing a previously existing notification channel ID, we need to make sure to use a unique value
// for `messagesNotificationChannelVersion`.
Clock clock = DI.get(Clock.class);
String messageNotificationChannelVersion = Long.toString(clock.getTime() / 1000);
String messageNotificationChannelVersion = Long.toString(clock.now().getEpochSeconds());
putString(editor, accountKeyPrefix + "messagesNotificationChannelVersion", messageNotificationChannelVersion);
AccountDescription imported = new AccountDescription(accountName, uuid);

View file

@ -1,6 +1,8 @@
package com.fsck.k9
import app.k9mail.core.testing.TestClock
import java.util.Calendar
import kotlinx.datetime.Instant
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
@ -111,6 +113,6 @@ class QuietTimeCheckerTest {
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay)
calendar.set(Calendar.MINUTE, minute)
clock.time = calendar.timeInMillis
clock.changeTimeTo(Instant.fromEpochMilliseconds(calendar.timeInMillis))
}
}

View file

@ -1,6 +1,6 @@
package com.fsck.k9.cache
import com.fsck.k9.TestClock
import app.k9mail.core.testing.TestClock
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

View file

@ -1,8 +1,9 @@
package com.fsck.k9.cache
import com.fsck.k9.TestClock
import app.k9mail.core.testing.TestClock
import com.google.common.truth.Truth.assertThat
import kotlin.test.Test
import kotlin.time.Duration.Companion.milliseconds
class ExpiringCacheTest {
@ -13,7 +14,7 @@ class ExpiringCacheTest {
@Test
fun `get should return null when entry present and cache expired`() {
testSubject[KEY] = VALUE
advanceClockBy(CACHE_TIME_VALIDITY_IN_MILLIS)
clock.advanceTimeBy(CACHE_TIME_VALIDITY_DURATION)
val result = testSubject[KEY]
@ -23,7 +24,7 @@ class ExpiringCacheTest {
@Test
fun `set should clear cache and add new entry when cache expired`() {
testSubject[KEY] = VALUE
advanceClockBy(CACHE_TIME_VALIDITY_IN_MILLIS)
clock.advanceTimeBy(CACHE_TIME_VALIDITY_DURATION)
testSubject[KEY + 1] = "$VALUE changed"
@ -34,7 +35,7 @@ class ExpiringCacheTest {
@Test
fun `hasKey should answer no when cache has entry and validity expired`() {
testSubject[KEY] = VALUE
advanceClockBy(CACHE_TIME_VALIDITY_IN_MILLIS)
clock.advanceTimeBy(CACHE_TIME_VALIDITY_DURATION)
assertThat(testSubject.hasKey(KEY)).isFalse()
}
@ -42,7 +43,7 @@ class ExpiringCacheTest {
@Test
fun `should keep cache when time progresses within expiration`() {
testSubject[KEY] = VALUE
advanceClockBy(CACHE_TIME_VALIDITY_IN_MILLIS - 1)
clock.advanceTimeBy(CACHE_TIME_VALIDITY_DURATION.minus(1L.milliseconds))
assertThat(testSubject[KEY]).isEqualTo(VALUE)
}
@ -51,18 +52,14 @@ class ExpiringCacheTest {
fun `should empty cache after time progresses to expiration`() {
testSubject[KEY] = VALUE
advanceClockBy(CACHE_TIME_VALIDITY_IN_MILLIS)
clock.advanceTimeBy(CACHE_TIME_VALIDITY_DURATION)
assertThat(testSubject[KEY]).isNull()
}
private fun advanceClockBy(timeInMillis: Long) {
clock.time = clock.time + timeInMillis
}
private companion object {
const val KEY = "key"
const val VALUE = "value"
const val CACHE_TIME_VALIDITY_IN_MILLIS = 30_000L
val CACHE_TIME_VALIDITY_DURATION = 30_000L.milliseconds
}
}

View file

@ -1,7 +1,7 @@
package com.fsck.k9.notification
import app.k9mail.core.testing.TestClock
import com.fsck.k9.Account
import com.fsck.k9.TestClock
import com.fsck.k9.controller.MessageReference
import com.fsck.k9.mailstore.LocalMessage
import com.fsck.k9.mailstore.LocalStore
@ -10,6 +10,7 @@ import com.fsck.k9.mailstore.MessageStoreManager
import com.fsck.k9.mailstore.NotificationMessage
import com.google.common.truth.Truth.assertThat
import kotlin.test.assertNotNull
import kotlinx.datetime.Instant
import org.junit.Test
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
@ -27,7 +28,7 @@ class NewMailNotificationManagerTest {
private val account = createAccount()
private val notificationContentCreator = mock<NotificationContentCreator>()
private val localStoreProvider = createLocalStoreProvider()
private val clock = TestClock(TIMESTAMP)
private val clock = TestClock(Instant.fromEpochMilliseconds(TIMESTAMP))
private val manager = NewMailNotificationManager(
notificationContentCreator,
createNotificationRepository(),
@ -82,7 +83,7 @@ class NewMailNotificationManagerTest {
)
manager.addNewMailNotification(account, messageOne, silent = false)
val timestamp = TIMESTAMP + 1000
clock.time = timestamp
clock.changeTimeTo(Instant.fromEpochMilliseconds(timestamp))
val result = manager.addNewMailNotification(account, messageTwo, silent = false)

View file

@ -1,11 +1,11 @@
package com.fsck.k9.notification
import app.k9mail.core.testing.TestClock
import com.fsck.k9.Account
import com.fsck.k9.Clock
import com.fsck.k9.K9
import com.fsck.k9.TestClock
import com.fsck.k9.controller.MessageReference
import com.google.common.truth.Truth.assertThat
import kotlinx.datetime.Clock
import org.junit.After
import org.junit.Before
import org.junit.Test

View file

@ -1,5 +0,0 @@
package com.fsck.k9
class TestClock(initialTime: Long = 0L) : Clock {
override var time: Long = initialTime
}

View file

@ -55,6 +55,7 @@ dependencies {
implementation(libs.glide)
annotationProcessor(libs.glide.compiler)
testImplementation(projects.core.testing)
testImplementation(projects.mail.testing)
testImplementation(projects.app.storage)
testImplementation(projects.app.testing)

View file

@ -9,18 +9,22 @@ import android.text.format.DateUtils.FORMAT_SHOW_DATE
import android.text.format.DateUtils.FORMAT_SHOW_TIME
import android.text.format.DateUtils.FORMAT_SHOW_WEEKDAY
import android.text.format.DateUtils.FORMAT_SHOW_YEAR
import com.fsck.k9.Clock
import java.util.Calendar
import java.util.Calendar.DAY_OF_WEEK
import java.util.Calendar.YEAR
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
/**
* Formatter to describe timestamps as a time relative to now.
*/
class RelativeDateTimeFormatter(private val context: Context, private val clock: Clock) {
class RelativeDateTimeFormatter(
private val context: Context,
private val clock: Clock,
) {
fun formatDate(timestamp: Long): String {
val now = clock.time.toCalendar()
val now = clock.now().toCalendar()
val date = timestamp.toCalendar()
val format = when {
date.isToday() -> FORMAT_SHOW_TIME
@ -38,6 +42,12 @@ private fun Long.toCalendar(): Calendar {
return calendar
}
private fun Instant.toCalendar(): Calendar {
val calendar = Calendar.getInstance()
calendar.timeInMillis = this.toEpochMilliseconds()
return calendar
}
private fun Calendar.isToday() = DateUtils.isToday(this.timeInMillis)
private fun Calendar.isWithinPastSevenDaysOf(other: Calendar) = this.before(other) &&

View file

@ -28,7 +28,6 @@ import app.k9mail.ui.utils.linearlayoutmanager.LinearLayoutManager
import com.fsck.k9.Account
import com.fsck.k9.Account.Expunge
import com.fsck.k9.Account.SortType
import com.fsck.k9.Clock
import com.fsck.k9.K9
import com.fsck.k9.Preferences
import com.fsck.k9.SwipeAction
@ -59,6 +58,7 @@ import com.google.android.material.floatingactionbutton.ExtendedFloatingActionBu
import com.google.android.material.snackbar.BaseTransientBottomBar.BaseCallback
import com.google.android.material.snackbar.Snackbar
import java.util.concurrent.Future
import kotlinx.datetime.Clock
import net.jcip.annotations.GuardedBy
import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.viewModel

View file

@ -2,12 +2,13 @@ package com.fsck.k9.ui.helper
import android.os.Build
import android.os.SystemClock
import app.k9mail.core.testing.TestClock
import com.fsck.k9.RobolectricTest
import com.fsck.k9.TestClock
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.TimeZone
import kotlinx.datetime.Instant
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
@ -125,7 +126,7 @@ class RelativeDateTimeFormatterTest : RobolectricTest() {
val dateTime = LocalDateTime.parse(time)
val timeInMillis = dateTime.toEpochMillis()
SystemClock.setCurrentTimeMillis(timeInMillis) // Is handled by ShadowSystemClock
clock.time = timeInMillis
clock.changeTimeTo(Instant.fromEpochMilliseconds(timeInMillis))
}
private fun String.toEpochMillis() = LocalDateTime.parse(this).toEpochMillis()

View file

@ -11,12 +11,12 @@ import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.isGone
import androidx.core.view.isVisible
import app.k9mail.core.testing.TestClock
import com.fsck.k9.Account
import com.fsck.k9.FontSizes
import com.fsck.k9.FontSizes.FONT_DEFAULT
import com.fsck.k9.FontSizes.LARGE
import com.fsck.k9.RobolectricTest
import com.fsck.k9.TestClock
import com.fsck.k9.UiDensity
import com.fsck.k9.contacts.ContactPictureLoader
import com.fsck.k9.mail.Address

View file

@ -26,5 +26,6 @@ android {
}
dependencies {
implementation(libs.bundles.shared.jvm.main)
testImplementation(libs.bundles.shared.jvm.test)
}

View file

@ -9,5 +9,6 @@ java {
}
dependencies {
implementation(libs.bundles.shared.jvm.main)
testImplementation(libs.bundles.shared.jvm.test)
}

View file

@ -174,7 +174,7 @@
<ID>LongParameterList:MessageDatabaseHelpers.kt$( type: Int = 0, root: Int? = null, parent: Int = -1, seq: Int = 0, mimeType: String = "text/plain", decodedBodySize: Int = 0, displayName: String? = null, header: String? = null, encoding: String = "7bit", charset: String? = null, dataLocation: Int = 0, data: ByteArray? = null, preamble: String? = null, epilogue: String? = null, boundary: String? = null, contentId: String? = null, serverExtra: String? = null, directory: File? = null, )</ID>
<ID>LongParameterList:MessageDetailsViewModel.kt$MessageDetailsViewModel$( private val resources: Resources, private val messageRepository: MessageRepository, private val folderRepository: FolderRepository, private val contactSettingsProvider: ContactSettingsProvider, private val contacts: Contacts, private val clipboardManager: ClipboardManager, private val accountManager: AccountManager, private val participantFormatter: MessageDetailsParticipantFormatter, private val folderNameFormatter: FolderNameFormatter, )</ID>
<ID>LongParameterList:MessageListAdapterTest.kt$MessageListAdapterTest$( account: Account = Account(SOME_ACCOUNT_UUID), subject: String? = "irrelevant", threadCount: Int = 0, messageDate: Long = 0L, internalDate: Long = 0L, displayName: CharSequence = "irrelevant", displayAddress: Address? = Address.parse("irrelevant@domain.example").first(), previewText: String = "irrelevant", isMessageEncrypted: Boolean = false, isRead: Boolean = false, isStarred: Boolean = false, isAnswered: Boolean = false, isForwarded: Boolean = false, hasAttachments: Boolean = false, uniqueId: Long = 0L, folderId: Long = 0L, messageUid: String = "irrelevant", databaseId: Long = 0L, threadRoot: Long = 0L, )</ID>
<ID>LongParameterList:MessageListAdapterTest.kt$MessageListAdapterTest$( fontSizes: FontSizes = createFontSizes(), previewLines: Int = 0, stars: Boolean = true, senderAboveSubject: Boolean = false, showContactPicture: Boolean = true, showingThreadedList: Boolean = true, backGroundAsReadIndicator: Boolean = false, showAccountChip: Boolean = false, )</ID>
<ID>LongParameterList:MessageListAdapterTest.kt$MessageListAdapterTest$( fontSizes: FontSizes = createFontSizes(), previewLines: Int = 0, stars: Boolean = true, senderAboveSubject: Boolean = false, showContactPicture: Boolean = true, showingThreadedList: Boolean = true, backGroundAsReadIndicator: Boolean = false, showAccountChip: Boolean = false, density: UiDensity = UiDensity.Default, )</ID>
<ID>LongParameterList:MessagePartDatabaseHelpers.kt$( type: Int = MessagePartType.UNKNOWN, root: Long? = null, parent: Long = -1, seq: Int = 0, mimeType: String? = null, decodedBodySize: Int? = null, displayName: String? = null, header: String? = null, encoding: String? = null, charset: String? = null, dataLocation: Int = DataLocation.MISSING, data: ByteArray? = null, preamble: String? = null, epilogue: String? = null, boundary: String? = null, contentId: String? = null, serverExtra: String? = null, )</ID>
<ID>LongParameterList:PasswordPromptDialogFragment.kt$PasswordPromptDialogFragment.Companion$( accountUuid: String, accountName: String, inputIncomingServerPassword: Boolean, incomingServerName: String?, inputOutgoingServerPassword: Boolean, outgoingServerName: String?, targetFragment: Fragment, requestCode: Int, )</ID>
<ID>LongParameterList:PushController.kt$PushController$( private val preferences: Preferences, private val generalSettingsManager: GeneralSettingsManager, private val backendManager: BackendManager, private val pushServiceManager: PushServiceManager, private val bootCompleteManager: BootCompleteManager, private val autoSyncManager: AutoSyncManager, private val pushNotificationManager: PushNotificationManager, private val connectivityManager: ConnectivityManager, private val accountPushControllerFactory: AccountPushControllerFactory, private val coroutineScope: CoroutineScope = GlobalScope, private val coroutineDispatcher: CoroutineDispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher(), )</ID>
@ -197,7 +197,6 @@
<ID>MagicNumber:Account.kt$Account$6</ID>
<ID>MagicNumber:Account.kt$Account$84</ID>
<ID>MagicNumber:Account.kt$Account.DeletePolicy.MARK_AS_READ$3</ID>
<ID>MagicNumber:AccountChip.kt$AccountChip$16</ID>
<ID>MagicNumber:AccountCreator.kt$AccountCreator$110</ID>
<ID>MagicNumber:AccountCreator.kt$AccountCreator$143</ID>
<ID>MagicNumber:AccountCreator.kt$AccountCreator$443</ID>

View file

@ -1,7 +1,3 @@
plugins {
id(ThunderbirdPlugins.Library.jvm)
}
dependencies {
implementation(libs.kotlinx.datetime)
}

View file

@ -1,5 +1,6 @@
package app.k9mail.core.testing
import kotlin.time.Duration
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
@ -11,4 +12,8 @@ class TestClock(
fun changeTimeTo(time: Instant) {
currentTime = time
}
fun advanceTimeBy(duration: Duration) {
currentTime += duration
}
}

View file

@ -2,29 +2,38 @@ package app.k9mail.core.testing
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import kotlinx.datetime.Instant
import kotlin.test.Test
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.datetime.Instant
internal class TestClockTest {
@Test
fun `should return the current time`() {
val testClock = TestClock()
val testClock = TestClock(Instant.DISTANT_PAST)
val currentTime = testClock.now()
assertThat(currentTime).isNotNull()
assertThat(currentTime).isEqualTo(Instant.DISTANT_PAST)
}
@Test
fun `should return the changed time`() {
val testClock = TestClock()
val testClock = TestClock(Instant.DISTANT_PAST)
testClock.changeTimeTo(Instant.DISTANT_FUTURE)
val currentTime = testClock.now()
assertThat(currentTime).isEqualTo(Instant.DISTANT_FUTURE)
}
@Test
fun `should advance time by duration`() {
val testClock = TestClock(Instant.DISTANT_PAST)
testClock.advanceTimeBy(1L.milliseconds)
val currentTime = testClock.now()
assertThat(currentTime).isEqualTo(Instant.DISTANT_PAST + 1L.milliseconds)
}
}

View file

@ -136,6 +136,9 @@ leakcanary-android = "com.squareup.leakcanary:leakcanary-android:2.9.1"
detekt-plugin-compose = "io.nlopez.compose.rules:detekt:0.1.1"
[bundles]
shared-jvm-main = [
"kotlinx-datetime",
]
shared-jvm-test = [
"junit",
"truth",