mirror of
https://github.com/tuskyapp/Tusky
synced 2024-12-22 23:08:04 +01:00
modernize tests (#4777)
- use `runTest` instead of `runBlocking`, where possible - run all Robolectric tests on Api 34 (where we have most users) - some new testcase for `TimestampUtilsTest` - move our only instrumented Android Test, `MigrationsTest`, to unit test so it runs in CI and expand it to test all migrations - upgrade Robolectric - removed truth and espresso as they are no longer needed
This commit is contained in:
parent
555ff1ea48
commit
29914f8fd9
@ -93,7 +93,9 @@ android {
|
||||
}
|
||||
}
|
||||
sourceSets {
|
||||
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
// workaround to have migrations available in unit tests
|
||||
// https://github.com/robolectric/robolectric/issues/3928#issuecomment-395309991
|
||||
debug.assets.srcDirs += files("$projectDir/schemas".toString())
|
||||
}
|
||||
|
||||
// Exclude unneeded files added by libraries
|
||||
@ -183,12 +185,8 @@ dependencies {
|
||||
testImplementation libs.bundles.mockito
|
||||
testImplementation libs.mockwebserver
|
||||
testImplementation libs.androidx.core.testing
|
||||
testImplementation libs.androidx.room.testing
|
||||
testImplementation libs.kotlinx.coroutines.test
|
||||
testImplementation libs.androidx.work.testing
|
||||
testImplementation libs.truth
|
||||
testImplementation libs.turbine
|
||||
|
||||
androidTestImplementation libs.espresso.core
|
||||
androidTestImplementation libs.androidx.room.testing
|
||||
androidTestImplementation libs.androidx.test.junit
|
||||
}
|
||||
|
@ -1,66 +0,0 @@
|
||||
package com.keylesspalace.tusky
|
||||
|
||||
import androidx.room.testing.MigrationTestHelper
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.keylesspalace.tusky.db.AppDatabase
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
const val TEST_DB = "migration_test"
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MigrationsTest {
|
||||
|
||||
@JvmField
|
||||
@Rule
|
||||
var helper: MigrationTestHelper = MigrationTestHelper(
|
||||
InstrumentationRegistry.getInstrumentation(),
|
||||
AppDatabase::class.java
|
||||
)
|
||||
|
||||
@Test
|
||||
fun migrateTo11() {
|
||||
val db = helper.createDatabase(TEST_DB, 10)
|
||||
|
||||
val id = 1
|
||||
val domain = "domain.site"
|
||||
val token = "token"
|
||||
val active = true
|
||||
val accountId = "accountId"
|
||||
val username = "username"
|
||||
val values = arrayOf(
|
||||
id, domain, token, active, accountId, username, "Display Name",
|
||||
"https://picture.url", true, true, true, true, true, true, true,
|
||||
true, "1000", "[]", "[{\"shortcode\": \"emoji\", \"url\": \"yes\"}]", 0, false,
|
||||
false, true
|
||||
)
|
||||
|
||||
db.execSQL(
|
||||
"INSERT OR REPLACE INTO `AccountEntity`(`id`,`domain`,`accessToken`,`isActive`," +
|
||||
"`accountId`,`username`,`displayName`,`profilePictureUrl`,`notificationsEnabled`," +
|
||||
"`notificationsMentioned`,`notificationsFollowed`,`notificationsReblogged`," +
|
||||
"`notificationsFavorited`,`notificationSound`,`notificationVibration`," +
|
||||
"`notificationLight`,`lastNotificationId`,`activeNotifications`,`emojis`," +
|
||||
"`defaultPostPrivacy`,`defaultMediaSensitivity`,`alwaysShowSensitiveMedia`," +
|
||||
"`mediaPreviewEnabled`) " +
|
||||
"VALUES (nullif(?, 0),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
values
|
||||
)
|
||||
|
||||
db.close()
|
||||
|
||||
val newDb = helper.runMigrationsAndValidate(TEST_DB, 11, true, AppDatabase.MIGRATION_10_11)
|
||||
|
||||
val cursor = newDb.query("SELECT * FROM AccountEntity")
|
||||
cursor.moveToFirst()
|
||||
assertEquals(id, cursor.getInt(0))
|
||||
assertEquals(domain, cursor.getString(1))
|
||||
assertEquals(token, cursor.getString(2))
|
||||
assertEquals(active, cursor.getInt(3) != 0)
|
||||
assertEquals(accountId, cursor.getString(4))
|
||||
assertEquals(username, cursor.getString(5))
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package android.text
|
||||
|
||||
// Used for stubbing Android implementation without slow & buggy Robolectric things
|
||||
@Suppress("unused")
|
||||
class SpannableString(private val text: CharSequence) : Spannable {
|
||||
|
||||
override fun setSpan(what: Any?, start: Int, end: Int, flags: Int) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun <T : Any?> getSpans(start: Int, end: Int, type: Class<T>?): Array<T> {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun removeSpan(what: Any?) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "FakeSpannableString[text=$text]"
|
||||
}
|
||||
|
||||
override val length: Int
|
||||
get() = text.length
|
||||
|
||||
override fun nextSpanTransition(start: Int, limit: Int, type: Class<*>?): Int {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun getSpanEnd(tag: Any?): Int {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun getSpanFlags(tag: Any?): Int {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun get(index: Int): Char {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun getSpanStart(tag: Any?): Int {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
}
|
@ -42,7 +42,7 @@ import org.robolectric.annotation.Config
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class FilterV1Test {
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class StatusComparisonTest {
|
||||
|
||||
|
@ -67,7 +67,7 @@ import retrofit2.Response
|
||||
* Created by charlag on 3/7/18.
|
||||
*/
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ComposeActivityTest {
|
||||
private lateinit var activity: ComposeActivity
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
package com.keylesspalace.tusky.components.compose
|
||||
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
@ -89,7 +89,7 @@ class ComposeTokenizerTest(
|
||||
|
||||
@Test
|
||||
fun tokenIndices_matchExpectations() {
|
||||
Assert.assertEquals(expectedStartIndex, tokenizer.findTokenStart(text, text.length))
|
||||
Assert.assertEquals(expectedEndIndex, tokenizer.findTokenEnd(text, text.length))
|
||||
assertEquals(expectedStartIndex, tokenizer.findTokenStart(text, text.length))
|
||||
assertEquals(expectedEndIndex, tokenizer.findTokenEnd(text, text.length))
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ComposeViewModelTest {
|
||||
|
||||
|
@ -27,7 +27,7 @@ import org.robolectric.ParameterizedRobolectricTestRunner
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@RunWith(ParameterizedRobolectricTestRunner::class)
|
||||
@Config(sdk = [33])
|
||||
@Config(sdk = [34])
|
||||
class StatusLengthTest(
|
||||
private val text: String,
|
||||
private val expectedLength: Int
|
||||
|
@ -38,7 +38,7 @@ import org.robolectric.annotation.Config
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NotificationsRemoteMediatorTest {
|
||||
|
||||
|
@ -37,7 +37,7 @@ import org.robolectric.annotation.Config
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class CachedTimelineRemoteMediatorTest {
|
||||
|
||||
|
@ -4,7 +4,7 @@ import androidx.paging.PagingSource
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.keylesspalace.tusky.components.timeline.viewmodel.NetworkTimelinePagingSource
|
||||
import com.keylesspalace.tusky.components.timeline.viewmodel.NetworkTimelineViewModel
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -12,7 +12,7 @@ import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NetworkTimelinePagingSourceTest {
|
||||
|
||||
@ -23,42 +23,36 @@ class NetworkTimelinePagingSourceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return empty list when params are Append`() {
|
||||
fun `should return empty list when params are Append`() = runTest {
|
||||
val pagingSource = NetworkTimelinePagingSource(timelineViewModel)
|
||||
|
||||
val params = PagingSource.LoadParams.Append("132", 20, false)
|
||||
|
||||
val expectedResult = PagingSource.LoadResult.Page(emptyList(), null, null)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(expectedResult, pagingSource.load(params))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return empty list when params are Prepend`() {
|
||||
fun `should return empty list when params are Prepend`() = runTest {
|
||||
val pagingSource = NetworkTimelinePagingSource(timelineViewModel)
|
||||
|
||||
val params = PagingSource.LoadParams.Prepend("132", 20, false)
|
||||
|
||||
val expectedResult = PagingSource.LoadResult.Page(emptyList(), null, null)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(expectedResult, pagingSource.load(params))
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return full list when params are Refresh`() {
|
||||
fun `should return full list when params are Refresh`() = runTest {
|
||||
val pagingSource = NetworkTimelinePagingSource(timelineViewModel)
|
||||
|
||||
val params = PagingSource.LoadParams.Refresh<String>(null, 20, false)
|
||||
|
||||
val expectedResult = PagingSource.LoadResult.Page(listOf(status), null, null)
|
||||
|
||||
runBlocking {
|
||||
val result = pagingSource.load(params)
|
||||
assertEquals(expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import com.keylesspalace.tusky.db.AccountManager
|
||||
import com.keylesspalace.tusky.db.entity.AccountEntity
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.Headers
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -30,7 +30,7 @@ import org.robolectric.annotation.Config
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
|
||||
@Config(sdk = [29])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@ -47,7 +47,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should return error when network call returns error code`() {
|
||||
fun `should return error when network call returns error code`() = runTest {
|
||||
val timelineViewModel: NetworkTimelineViewModel = mock {
|
||||
on { statusData } doReturn mutableListOf()
|
||||
onBlocking { fetchStatusesForKind(anyOrNull(), anyOrNull(), anyOrNull()) } doReturn Response.error(500, "".toResponseBody())
|
||||
@ -55,7 +55,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
val remoteMediator = NetworkTimelineRemoteMediator(accountManager, timelineViewModel)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.REFRESH, state()) }
|
||||
val result = remoteMediator.load(LoadType.REFRESH, state())
|
||||
|
||||
assertTrue(result is RemoteMediator.MediatorResult.Error)
|
||||
assertTrue((result as RemoteMediator.MediatorResult.Error).throwable is HttpException)
|
||||
@ -64,7 +64,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should return error when network call fails`() {
|
||||
fun `should return error when network call fails`() = runTest {
|
||||
val timelineViewModel: NetworkTimelineViewModel = mock {
|
||||
on { statusData } doReturn mutableListOf()
|
||||
onBlocking { fetchStatusesForKind(anyOrNull(), anyOrNull(), anyOrNull()) } doThrow IOException()
|
||||
@ -72,7 +72,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
val remoteMediator = NetworkTimelineRemoteMediator(accountManager, timelineViewModel)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.REFRESH, state()) }
|
||||
val result = remoteMediator.load(LoadType.REFRESH, state())
|
||||
|
||||
assertTrue(result is RemoteMediator.MediatorResult.Error)
|
||||
assertTrue((result as RemoteMediator.MediatorResult.Error).throwable is IOException)
|
||||
@ -80,7 +80,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should do initial loading`() {
|
||||
fun `should do initial loading`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf()
|
||||
|
||||
val timelineViewModel: NetworkTimelineViewModel = mock {
|
||||
@ -111,7 +111,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.REFRESH, state) }
|
||||
val result = remoteMediator.load(LoadType.REFRESH, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("7"),
|
||||
@ -127,7 +127,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should not prepend statuses`() {
|
||||
fun `should not prepend statuses`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("3"),
|
||||
fakeStatusViewData("2"),
|
||||
@ -162,7 +162,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.REFRESH, state) }
|
||||
val result = remoteMediator.load(LoadType.REFRESH, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("5"),
|
||||
@ -179,7 +179,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should refresh and insert placeholder`() {
|
||||
fun `should refresh and insert placeholder`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("3"),
|
||||
fakeStatusViewData("2"),
|
||||
@ -214,7 +214,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.REFRESH, state) }
|
||||
val result = remoteMediator.load(LoadType.REFRESH, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("10"),
|
||||
@ -232,7 +232,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should refresh and not insert placeholders`() {
|
||||
fun `should refresh and not insert placeholders`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
fakeStatusViewData("7"),
|
||||
@ -267,7 +267,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.APPEND, state) }
|
||||
val result = remoteMediator.load(LoadType.APPEND, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
@ -285,7 +285,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should append statuses`() {
|
||||
fun `should append statuses`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
fakeStatusViewData("7"),
|
||||
@ -324,7 +324,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.APPEND, state) }
|
||||
val result = remoteMediator.load(LoadType.APPEND, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
@ -342,7 +342,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should not append statuses when pagination end has been reached`() {
|
||||
fun `should not append statuses when pagination end has been reached`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
fakeStatusViewData("7"),
|
||||
@ -370,7 +370,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.APPEND, state) }
|
||||
val result = remoteMediator.load(LoadType.APPEND, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("8"),
|
||||
@ -385,7 +385,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
|
||||
@Test
|
||||
@ExperimentalPagingApi
|
||||
fun `should not append duplicates for trending statuses`() {
|
||||
fun `should not append duplicates for trending statuses`() = runTest {
|
||||
val statuses: MutableList<StatusViewData> = mutableListOf(
|
||||
fakeStatusViewData("5"),
|
||||
fakeStatusViewData("4"),
|
||||
@ -421,7 +421,7 @@ class NetworkTimelineRemoteMediatorTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = runBlocking { remoteMediator.load(LoadType.APPEND, state) }
|
||||
val result = remoteMediator.load(LoadType.APPEND, state)
|
||||
|
||||
val newStatusData = mutableListOf(
|
||||
fakeStatusViewData("5"),
|
||||
|
@ -22,7 +22,7 @@ import com.keylesspalace.tusky.network.MastodonApi
|
||||
import com.keylesspalace.tusky.usecase.TimelineCases
|
||||
import java.io.IOException
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
@ -35,7 +35,7 @@ import org.mockito.kotlin.stub
|
||||
import org.robolectric.Shadows.shadowOf
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ViewThreadViewModelTest {
|
||||
|
||||
@ -113,12 +113,11 @@ class ViewThreadViewModelTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit status and context when both load`() {
|
||||
fun `should emit status and context when both load`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -132,10 +131,9 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit status even if context fails to load`() {
|
||||
fun `should emit status even if context fails to load`() = runTest {
|
||||
api.stub {
|
||||
onBlocking { status(threadId) } doReturn NetworkResult.success(fakeStatus(id = "2", inReplyToId = "1", inReplyToAccountId = "1"))
|
||||
onBlocking { statusContext(threadId) } doReturn NetworkResult.failure(IOException())
|
||||
@ -143,7 +141,6 @@ class ViewThreadViewModelTest {
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -155,10 +152,9 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit error when status and context fail to load`() {
|
||||
fun `should emit error when status and context fail to load`() = runTest {
|
||||
api.stub {
|
||||
onBlocking { status(threadId) } doReturn NetworkResult.failure(IOException())
|
||||
onBlocking { statusContext(threadId) } doReturn NetworkResult.failure(IOException())
|
||||
@ -166,16 +162,14 @@ class ViewThreadViewModelTest {
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Error::class.java,
|
||||
viewModel.uiState.first().javaClass
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should emit error when status fails to load`() {
|
||||
fun `should emit error when status fails to load`() = runTest {
|
||||
api.stub {
|
||||
onBlocking { status(threadId) } doReturn NetworkResult.failure(IOException())
|
||||
onBlocking { statusContext(threadId) } doReturn NetworkResult.success(
|
||||
@ -188,22 +182,19 @@ class ViewThreadViewModelTest {
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Error::class.java,
|
||||
viewModel.uiState.first().javaClass
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should update state when reveal button is toggled`() {
|
||||
fun `should update state when reveal button is toggled`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
viewModel.toggleRevealButton()
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -217,15 +208,13 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should handle status changed event`() {
|
||||
fun `should handle status changed event`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
eventHub.dispatch(StatusChangedEvent(fakeStatus(id = "1", spoilerText = "Test", favourited = false)))
|
||||
|
||||
assertEquals(
|
||||
@ -241,17 +230,15 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should remove status`() {
|
||||
fun `should remove status`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
viewModel.removeStatus(fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test"))
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -264,10 +251,9 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change status expanded state`() {
|
||||
fun `should change status expanded state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
@ -277,7 +263,6 @@ class ViewThreadViewModelTest {
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -291,10 +276,9 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change content collapsed state`() {
|
||||
fun `should change content collapsed state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
@ -304,7 +288,6 @@ class ViewThreadViewModelTest {
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -318,10 +301,9 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change content showing state`() {
|
||||
fun `should change content showing state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
@ -331,7 +313,6 @@ class ViewThreadViewModelTest {
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
@ -345,7 +326,6 @@ class ViewThreadViewModelTest {
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mockSuccessResponses() {
|
||||
api.stub {
|
||||
|
@ -0,0 +1,87 @@
|
||||
package com.keylesspalace.tusky.db
|
||||
|
||||
import androidx.room.testing.MigrationTestHelper
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import com.keylesspalace.tusky.di.StorageModule
|
||||
import com.keylesspalace.tusky.entity.Emoji
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class MigrationsTest {
|
||||
|
||||
@get:Rule
|
||||
val migrationHelper = MigrationTestHelper(
|
||||
InstrumentationRegistry.getInstrumentation(),
|
||||
AppDatabase::class.java
|
||||
)
|
||||
|
||||
@Test
|
||||
fun testMigrations() {
|
||||
/** the db name must match the one in [StorageModule.providesDatabase] */
|
||||
val db = migrationHelper.createDatabase("tuskyDB", 10)
|
||||
val moshi = Moshi.Builder().build()
|
||||
|
||||
val id = 1L
|
||||
val domain = "domain.site"
|
||||
val token = "token"
|
||||
val active = true
|
||||
val accountId = "accountId"
|
||||
val username = "username"
|
||||
val emoji = moshi.adapter<List<Emoji>>(Types.newParameterizedType(List::class.java, Emoji::class.java), emptySet()).toJson(
|
||||
listOf(
|
||||
Emoji(
|
||||
shortcode = "testemoji",
|
||||
url = "https://some.url",
|
||||
staticUrl = "https://some.url",
|
||||
visibleInPicker = true,
|
||||
category = null
|
||||
)
|
||||
)
|
||||
)
|
||||
val values = arrayOf(
|
||||
id, domain, token, active, accountId, username, "Display Name",
|
||||
"https://picture.url", true, true, true, true, true, true, true,
|
||||
true, "1000", "[]", emoji, 0, false,
|
||||
false, true
|
||||
)
|
||||
|
||||
db.execSQL(
|
||||
"INSERT OR REPLACE INTO `AccountEntity`(`id`,`domain`,`accessToken`,`isActive`," +
|
||||
"`accountId`,`username`,`displayName`,`profilePictureUrl`,`notificationsEnabled`," +
|
||||
"`notificationsMentioned`,`notificationsFollowed`,`notificationsReblogged`," +
|
||||
"`notificationsFavorited`,`notificationSound`,`notificationVibration`," +
|
||||
"`notificationLight`,`lastNotificationId`,`activeNotifications`,`emojis`," +
|
||||
"`defaultPostPrivacy`,`defaultMediaSensitivity`,`alwaysShowSensitiveMedia`," +
|
||||
"`mediaPreviewEnabled`) " +
|
||||
"VALUES (nullif(?, 0),?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
|
||||
values
|
||||
)
|
||||
|
||||
db.close()
|
||||
|
||||
// Room will run all migrations and validate the scheme afterwards
|
||||
val roomDb = StorageModule.providesDatabase(
|
||||
InstrumentationRegistry.getInstrumentation().context,
|
||||
Converters(moshi)
|
||||
)
|
||||
|
||||
val account = roomDb.accountDao().loadAll().first()
|
||||
|
||||
roomDb.close()
|
||||
|
||||
assertEquals(id, account.id)
|
||||
assertEquals(domain, account.domain)
|
||||
assertEquals(token, account.accessToken)
|
||||
assertEquals(active, account.isActive)
|
||||
assertEquals(accountId, account.accountId)
|
||||
assertEquals(username, account.username)
|
||||
}
|
||||
}
|
@ -28,7 +28,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class DatabaseCleanerTest {
|
||||
private lateinit var timelineDao: TimelineDao
|
||||
|
@ -25,7 +25,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class NotificationsDaoTest {
|
||||
private lateinit var notificationsDao: NotificationsDao
|
||||
|
@ -19,7 +19,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimelineDaoTest {
|
||||
private lateinit var timelineDao: TimelineDao
|
||||
|
@ -1,46 +1,48 @@
|
||||
package com.keylesspalace.tusky.entity
|
||||
|
||||
import com.keylesspalace.tusky.settings.ProxyConfiguration
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class ProxyConfigurationTest {
|
||||
@Test
|
||||
fun `serialized non-int is not valid proxy port`() {
|
||||
Assert.assertFalse(ProxyConfiguration.isValidProxyPort("should fail"))
|
||||
Assert.assertFalse(ProxyConfiguration.isValidProxyPort("1.5"))
|
||||
assertFalse(ProxyConfiguration.isValidProxyPort("should fail"))
|
||||
assertFalse(ProxyConfiguration.isValidProxyPort("1.5"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `number outside port range is not valid`() {
|
||||
Assert.assertFalse(ProxyConfiguration.isValidProxyPort("${ProxyConfiguration.MIN_PROXY_PORT - 1}"))
|
||||
Assert.assertFalse(ProxyConfiguration.isValidProxyPort("${ProxyConfiguration.MAX_PROXY_PORT + 1}"))
|
||||
assertFalse(ProxyConfiguration.isValidProxyPort("${ProxyConfiguration.MIN_PROXY_PORT - 1}"))
|
||||
assertFalse(ProxyConfiguration.isValidProxyPort("${ProxyConfiguration.MAX_PROXY_PORT + 1}"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `number in port range, inclusive of min and max, is valid`() {
|
||||
Assert.assertTrue(ProxyConfiguration.isValidProxyPort(ProxyConfiguration.MIN_PROXY_PORT))
|
||||
Assert.assertTrue(ProxyConfiguration.isValidProxyPort(ProxyConfiguration.MAX_PROXY_PORT))
|
||||
Assert.assertTrue(ProxyConfiguration.isValidProxyPort((ProxyConfiguration.MIN_PROXY_PORT + ProxyConfiguration.MAX_PROXY_PORT) / 2))
|
||||
assertTrue(ProxyConfiguration.isValidProxyPort(ProxyConfiguration.MIN_PROXY_PORT))
|
||||
assertTrue(ProxyConfiguration.isValidProxyPort(ProxyConfiguration.MAX_PROXY_PORT))
|
||||
assertTrue(ProxyConfiguration.isValidProxyPort((ProxyConfiguration.MIN_PROXY_PORT + ProxyConfiguration.MAX_PROXY_PORT) / 2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create with invalid port yields null`() {
|
||||
Assert.assertNull(ProxyConfiguration.create("hostname", ProxyConfiguration.MIN_PROXY_PORT - 1))
|
||||
assertNull(ProxyConfiguration.create("hostname", ProxyConfiguration.MIN_PROXY_PORT - 1))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create with invalid hostname yields null`() {
|
||||
Assert.assertNull(ProxyConfiguration.create(".", ProxyConfiguration.MIN_PROXY_PORT))
|
||||
assertNull(ProxyConfiguration.create(".", ProxyConfiguration.MIN_PROXY_PORT))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `create with valid hostname and port yields the config object`() {
|
||||
Assert.assertTrue(ProxyConfiguration.create("hostname", ProxyConfiguration.MIN_PROXY_PORT) is ProxyConfiguration)
|
||||
assertTrue(ProxyConfiguration.create("hostname", ProxyConfiguration.MIN_PROXY_PORT) is ProxyConfiguration)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `unicode hostname allowed`() {
|
||||
Assert.assertTrue(ProxyConfiguration.create("federação.social", ProxyConfiguration.MIN_PROXY_PORT) is ProxyConfiguration)
|
||||
assertTrue(ProxyConfiguration.create("federação.social", ProxyConfiguration.MIN_PROXY_PORT) is ProxyConfiguration)
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import com.keylesspalace.tusky.appstore.StatusChangedEvent
|
||||
import com.keylesspalace.tusky.entity.Status
|
||||
import com.keylesspalace.tusky.network.MastodonApi
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import okhttp3.ResponseBody.Companion.toResponseBody
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
@ -21,7 +21,7 @@ import org.robolectric.annotation.Config
|
||||
import retrofit2.HttpException
|
||||
import retrofit2.Response
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimelineCasesTest {
|
||||
|
||||
@ -39,23 +39,21 @@ class TimelineCasesTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pin success emits StatusChangedEvent`() {
|
||||
fun `pin success emits StatusChangedEvent`() = runTest {
|
||||
val pinnedStatus = mockStatus(pinned = true)
|
||||
|
||||
api.stub {
|
||||
onBlocking { pinStatus(statusId) } doReturn NetworkResult.success(pinnedStatus)
|
||||
}
|
||||
|
||||
runBlocking {
|
||||
eventHub.events.test {
|
||||
timelineCases.pin(statusId, true)
|
||||
assertEquals(StatusChangedEvent(pinnedStatus), awaitItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pin failure with server error throws TimelineError with server message`() {
|
||||
fun `pin failure with server error throws TimelineError with server message`() = runTest {
|
||||
api.stub {
|
||||
onBlocking { pinStatus(statusId) } doReturn NetworkResult.failure(
|
||||
HttpException(
|
||||
@ -66,13 +64,11 @@ class TimelineCasesTest {
|
||||
)
|
||||
)
|
||||
}
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
"Validation Failed: You have already pinned the maximum number of toots",
|
||||
timelineCases.pin(statusId, true).exceptionOrNull()?.message
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun mockStatus(pinned: Boolean = false): Status {
|
||||
return Status(
|
||||
|
@ -1,13 +1,8 @@
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class HttpHeaderLinkTest {
|
||||
data class TestData(val name: String, val input: String, val want: List<HttpHeaderLink>)
|
||||
|
||||
|
@ -19,7 +19,7 @@ import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LinkHelperTest {
|
||||
private val listener = object : LinkListener {
|
||||
|
@ -4,45 +4,47 @@ import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.os.LocaleListCompat
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.keylesspalace.tusky.db.entity.AccountEntity
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertArrayEquals
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class LocaleUtilsTest {
|
||||
@Test
|
||||
fun initialLanguagesContainReplySelectedAppAndSystem() {
|
||||
val expectedLanguages = arrayOf<String?>("yi", "tok", "da", "fr", "sv", "kab")
|
||||
val languages = getMockedInitialLanguages(expectedLanguages)
|
||||
Assert.assertArrayEquals(expectedLanguages, languages.subList(0, expectedLanguages.size).toTypedArray())
|
||||
assertArrayEquals(expectedLanguages, languages.subList(0, expectedLanguages.size).toTypedArray())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun whenReplyLanguageIsNull_DefaultLanguageIsFirst() {
|
||||
val defaultLanguage = "tok"
|
||||
val languages = getMockedInitialLanguages(arrayOf(null, defaultLanguage, "da", "fr", "sv", "kab"))
|
||||
Assert.assertEquals(defaultLanguage, languages[0])
|
||||
assertEquals(defaultLanguage, languages[0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun initialLanguagesAreDistinct() {
|
||||
val defaultLanguage = "da"
|
||||
val languages = getMockedInitialLanguages(arrayOf(defaultLanguage, defaultLanguage, "fr", defaultLanguage, "kab", defaultLanguage))
|
||||
Assert.assertEquals(1, languages.count { it == defaultLanguage })
|
||||
assertEquals(1, languages.count { it == defaultLanguage })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun initialLanguageDeduplicationDoesNotReorder() {
|
||||
val defaultLanguage = "da"
|
||||
|
||||
Assert.assertEquals(
|
||||
assertEquals(
|
||||
defaultLanguage,
|
||||
getMockedInitialLanguages(arrayOf(defaultLanguage, defaultLanguage, "fr", defaultLanguage, "kab", defaultLanguage))[0]
|
||||
)
|
||||
Assert.assertEquals(
|
||||
assertEquals(
|
||||
defaultLanguage,
|
||||
getMockedInitialLanguages(arrayOf(null, defaultLanguage, "fr", defaultLanguage, "kab", defaultLanguage))[0]
|
||||
)
|
||||
@ -51,7 +53,7 @@ class LocaleUtilsTest {
|
||||
@Test
|
||||
fun emptyInitialLanguagesAreDropped() {
|
||||
val languages = getMockedInitialLanguages(arrayOf("", "", "fr", "", "kab", ""))
|
||||
Assert.assertFalse(languages.any { it.isEmpty() })
|
||||
assertFalse(languages.any { it.isEmpty() })
|
||||
}
|
||||
|
||||
private fun getMockedInitialLanguages(configuredLanguages: Array<String?>): List<String> {
|
||||
|
@ -3,7 +3,7 @@ package com.keylesspalace.tusky.util
|
||||
import java.util.Locale
|
||||
import kotlin.math.pow
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
@ -65,6 +65,6 @@ class NumberUtilsTest(private val input: Long, private val want: String) {
|
||||
|
||||
@Test
|
||||
fun test() {
|
||||
Assert.assertEquals(want, formatNumber(input, 1000))
|
||||
assertEquals(want, formatNumber(input, 1000))
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import org.junit.runner.RunWith
|
||||
import org.robolectric.Robolectric
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class RickRollTest {
|
||||
private lateinit var activity: Activity
|
||||
|
@ -8,7 +8,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SmartLengthInputFilterTest {
|
||||
|
||||
|
@ -1,29 +1,78 @@
|
||||
package com.keylesspalace.tusky.util
|
||||
|
||||
import android.content.Context
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.keylesspalace.tusky.R
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import java.util.Locale
|
||||
import kotlin.time.Duration.Companion.days
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.BeforeClass
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.mock
|
||||
import org.robolectric.annotation.Config
|
||||
|
||||
private const val STATUS_CREATED_AT_NOW = "test"
|
||||
|
||||
@Config(sdk = [28])
|
||||
@Config(sdk = [34])
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class TimestampUtilsTest {
|
||||
private val ctx: Context = mock {
|
||||
on { getString(R.string.status_created_at_now) } doReturn STATUS_CREATED_AT_NOW
|
||||
|
||||
companion object {
|
||||
private lateinit var locale: Locale
|
||||
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun beforeClass() {
|
||||
locale = Locale.getDefault()
|
||||
Locale.setDefault(Locale.ENGLISH)
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@JvmStatic
|
||||
fun afterClass() {
|
||||
Locale.setDefault(locale)
|
||||
}
|
||||
}
|
||||
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
|
||||
@Test
|
||||
fun `should return 'now' for small timespans`() {
|
||||
assertEquals("now", getRelativeTimeSpanString(context, 0, 300))
|
||||
assertEquals("now", getRelativeTimeSpanString(context, 300, 0))
|
||||
assertEquals("now", getRelativeTimeSpanString(context, 501, 0))
|
||||
assertEquals("now", getRelativeTimeSpanString(context, 0, 999))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldShowNowForSmallTimeSpans() {
|
||||
assertEquals(STATUS_CREATED_AT_NOW, getRelativeTimeSpanString(ctx, 0, 300))
|
||||
assertEquals(STATUS_CREATED_AT_NOW, getRelativeTimeSpanString(ctx, 300, 0))
|
||||
assertEquals(STATUS_CREATED_AT_NOW, getRelativeTimeSpanString(ctx, 501, 0))
|
||||
assertEquals(STATUS_CREATED_AT_NOW, getRelativeTimeSpanString(ctx, 0, 999))
|
||||
fun `should return 'in --' when then is after now`() {
|
||||
assertEquals("in 49s", getRelativeTimeSpanString(context, 49.seconds.inWholeMilliseconds, 0))
|
||||
assertEquals("in 34m", getRelativeTimeSpanString(context, 37.minutes.inWholeMilliseconds, 3.minutes.inWholeMilliseconds))
|
||||
assertEquals("in 7h", getRelativeTimeSpanString(context, 10.hours.inWholeMilliseconds, 3.hours.inWholeMilliseconds))
|
||||
assertEquals("in 10d", getRelativeTimeSpanString(context, 10.days.inWholeMilliseconds, 0))
|
||||
assertEquals("in 4y", getRelativeTimeSpanString(context, 800.days.inWholeMilliseconds + (4 * 365).days.inWholeMilliseconds, 800.days.inWholeMilliseconds))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return correct timespans`() {
|
||||
assertEquals("49s", getRelativeTimeSpanString(context, 0, 49.seconds.inWholeMilliseconds))
|
||||
assertEquals("34m", getRelativeTimeSpanString(context, 3.minutes.inWholeMilliseconds, 37.minutes.inWholeMilliseconds))
|
||||
assertEquals("7h", getRelativeTimeSpanString(context, 3.hours.inWholeMilliseconds, 10.hours.inWholeMilliseconds))
|
||||
assertEquals("10d", getRelativeTimeSpanString(context, 0, 10.days.inWholeMilliseconds))
|
||||
assertEquals("4y", getRelativeTimeSpanString(context, 800.days.inWholeMilliseconds, 800.days.inWholeMilliseconds + (4 * 365).days.inWholeMilliseconds))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return correct poll duration`() {
|
||||
assertEquals("1 second left", formatPollDuration(context, 1.seconds.inWholeMilliseconds, 0))
|
||||
assertEquals("49 seconds left", formatPollDuration(context, 49.seconds.inWholeMilliseconds, 0))
|
||||
assertEquals("1 minute left", formatPollDuration(context, 37.minutes.inWholeMilliseconds, 36.minutes.inWholeMilliseconds))
|
||||
assertEquals("34 minutes left", formatPollDuration(context, 37.minutes.inWholeMilliseconds, 3.minutes.inWholeMilliseconds))
|
||||
assertEquals("1 hour left", formatPollDuration(context, 10.hours.inWholeMilliseconds, 9.hours.inWholeMilliseconds))
|
||||
assertEquals("7 hours left", formatPollDuration(context, 10.hours.inWholeMilliseconds, 3.hours.inWholeMilliseconds))
|
||||
assertEquals("1 day left", formatPollDuration(context, 1.days.inWholeMilliseconds, 0))
|
||||
assertEquals("10 days left", formatPollDuration(context, 10.days.inWholeMilliseconds, 0))
|
||||
assertEquals("1460 days left", formatPollDuration(context, 800.days.inWholeMilliseconds + (4 * 365).days.inWholeMilliseconds, 800.days.inWholeMilliseconds))
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ conscrypt = "2.5.3"
|
||||
coroutines = "1.9.0"
|
||||
diffx = "1.1.1"
|
||||
emoji2 = "1.4.0"
|
||||
espresso = "3.6.1"
|
||||
filemoji-compat = "3.2.7"
|
||||
glide = "4.16.0"
|
||||
# Deliberate downgrade, https://github.com/tuskyapp/Tusky/issues/3631
|
||||
@ -46,10 +45,9 @@ networkresult-calladapter = "1.2.0"
|
||||
okhttp = "4.12.0"
|
||||
okio = "3.9.1"
|
||||
retrofit = "2.11.0"
|
||||
robolectric = "4.13"
|
||||
robolectric = "4.14.1"
|
||||
sparkbutton = "4.2.0"
|
||||
touchimageview = "3.6"
|
||||
truth = "1.4.4"
|
||||
turbine = "1.2.0"
|
||||
unified-push = "2.4.0"
|
||||
xmlwriter = "1.0.4"
|
||||
@ -102,7 +100,6 @@ conscrypt-android = { module = "org.conscrypt:conscrypt-android", version.ref =
|
||||
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
|
||||
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
|
||||
diffx = { module = "org.pageseeder.diffx:pso-diffx", version.ref = "diffx" }
|
||||
espresso-core = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
|
||||
filemojicompat-core = { module = "de.c1710:filemojicompat", version.ref = "filemoji-compat" }
|
||||
filemojicompat-defaults = { module = "de.c1710:filemojicompat-defaults", version.ref = "filemoji-compat" }
|
||||
filemojicompat-ui = { module = "de.c1710:filemojicompat-ui", version.ref = "filemoji-compat" }
|
||||
@ -131,7 +128,6 @@ retrofit-core = { module = "com.squareup.retrofit2:retrofit", version.ref = "ret
|
||||
robolectric = { module = "org.robolectric:robolectric", version.ref = "robolectric" }
|
||||
sparkbutton = { module = "at.connyduck.sparkbutton:sparkbutton", version.ref = "sparkbutton" }
|
||||
touchimageview = { module = "com.github.MikeOrtiz:TouchImageView", version.ref = "touchimageview" }
|
||||
truth = { module = "com.google.truth:truth", version.ref = "truth" }
|
||||
turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" }
|
||||
unified-push = { module = "com.github.UnifiedPush:android-connector", version.ref = "unified-push" }
|
||||
xmlwriter = { module = "org.pageseeder.xmlwriter:pso-xmlwriter", version.ref = "xmlwriter" }
|
||||
|
@ -2761,6 +2761,14 @@
|
||||
<sha256 value="41cebc18bbfee1fef5c0c06aaa1e3cb74658bc25bd720c80719d087da0ad02e7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test" name="monitor" version="1.7.2">
|
||||
<artifact name="monitor-1.7.2.aar">
|
||||
<sha256 value="868cc120d10d024b886fa157e1e1eaee0e6a8e5d55e7f765ef41d8fc0fea775b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="monitor-1.7.2.pom">
|
||||
<sha256 value="388fe58cf6062ffcce209853ac5c006d1d6efee9ba76b16fabfb45a7f26521ce" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="androidx.test" name="runner" version="1.5.2">
|
||||
<artifact name="runner-1.5.2-sources.jar">
|
||||
<sha256 value="188f6e40732dda9451d70121a12a31f6411bb3ae598d58193e494ff27e111700" origin="Generated by Gradle"/>
|
||||
@ -8967,6 +8975,14 @@
|
||||
<sha256 value="2a01226a8509dbd2b6da8008aaacf6fb4f83198ee1f2666cbabd4a19a3f98197" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_annotation" version="2.34.0">
|
||||
<artifact name="error_prone_annotation-2.34.0.jar">
|
||||
<sha256 value="99f8b53c75a50617d4f9bf45512eda82e7d8e9eb377471d822d3d4c4e034c510" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="error_prone_annotation-2.34.0.pom">
|
||||
<sha256 value="439962cc28110faaf17721c1ff4c588d31ec6f3a1a8bfad035b4215a4c408fdd" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_annotations" version="2.11.0">
|
||||
<artifact name="error_prone_annotations-2.11.0.pom">
|
||||
<sha256 value="0261ca01f2d2e9ac2ae2ece75d42c56323b385fb294b6bc943f62ef4e92ddf08" origin="Generated by Gradle"/>
|
||||
@ -9060,6 +9076,11 @@
|
||||
<sha256 value="767525d9a81129cd081968382980336327be4162b1e2251a182911daa733c123" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="error_prone_parent" version="2.34.0">
|
||||
<artifact name="error_prone_parent-2.34.0.pom">
|
||||
<sha256 value="9db673b33ad310735c6467dd6f6606290e609e867a62e5bad8f9b3365db7188e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.errorprone" name="javac-shaded" version="9-dev-r4023-3">
|
||||
<artifact name="javac-shaded-9-dev-r4023-3.jar">
|
||||
<sha256 value="65bfccf60986c47fbc17c9ebab0be626afc41741e0a6ec7109e0768817a36f30" origin="Generated by Gradle"/>
|
||||
@ -9159,6 +9180,17 @@
|
||||
<sha256 value="452b2d9787b7d366fa8cf5ed9a1c40404542d05effa7a598da03bbbbb76d9f31" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava" version="33.3.1-jre">
|
||||
<artifact name="guava-33.3.1-android.jar">
|
||||
<sha256 value="2c3e41d1b380f2044d257947a3aa82dabf3ae4b978622745254aa18b6cf89ab0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="guava-33.3.1-jre.jar">
|
||||
<sha256 value="4bf0e2c5af8e4525c96e8fde17a4f7307f97f8478f11c4c8e35a0e3298ae4e90" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="guava-33.3.1-jre.module">
|
||||
<sha256 value="41858c84753fd96a6b7c51122fccef39558c91cc08264e08506bcf20e0e63733" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava-parent" version="26.0-android">
|
||||
<artifact name="guava-parent-26.0-android.pom">
|
||||
<sha256 value="f8698ab46ca996ce889c1afc8ca4f25eb8ac6b034dc898d4583742360016cc04" origin="Generated by Gradle"/>
|
||||
@ -9194,6 +9226,11 @@
|
||||
<sha256 value="5af287a2deb741f38c24a0b390a7a388faee5d7cf0edc4c7b7b98559a5f29fbf" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="guava-parent" version="33.3.1-jre">
|
||||
<artifact name="guava-parent-33.3.1-jre.pom">
|
||||
<sha256 value="55441db27e8869dfefe053059bdf478bdc7e95585642bf391f0023345fd56287" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.guava" name="listenablefuture" version="1.0">
|
||||
<artifact name="listenablefuture-1.0-sources.jar">
|
||||
<sha256 value="3d1bd8d4a39b293612a40e547ec51d9ce34fa638d7adeae83871cdbe2923b161" origin="Generated by Gradle"/>
|
||||
@ -9321,6 +9358,19 @@
|
||||
<sha256 value="0f022a32490b76449f7404b0506dace458aeaa97c8300b34cfd5be1af1ac992b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.testparameterinjector" name="test-parameter-injector" version="1.18">
|
||||
<artifact name="test-parameter-injector-1.18.jar">
|
||||
<sha256 value="e5a7c649c54c412049908247ca5e25fe6921d746849c6017a84dc6044237a4b4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="test-parameter-injector-1.18.pom">
|
||||
<sha256 value="de05732fbdcb5b05e19985abc0a284e41be3ec685387d04f8488a5e6504ea08e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.testparameterinjector" name="test-parameter-injector-parent" version="1.18">
|
||||
<artifact name="test-parameter-injector-parent-1.18.pom">
|
||||
<sha256 value="b4aee6be3f6dfafa68309e9da4fb38af7fbc2f8c3e26197451f1db38dc4a85d0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="com.google.truth" name="truth" version="1.4.2">
|
||||
<artifact name="truth-1.4.2-sources.jar">
|
||||
<sha256 value="9e6e49a3d2eefcadc0294878cb19fa6c6da305f2939c422f3cbd8caf9efe80bb" origin="Generated by Gradle"/>
|
||||
@ -10623,6 +10673,14 @@
|
||||
<sha256 value="e0fa622b7de63eae11047ef6e91b4c2ad0f1f0e13cb903ff52080a47f57a5746" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.checkerframework" name="checker-qual" version="3.43.0">
|
||||
<artifact name="checker-qual-3.43.0.jar">
|
||||
<sha256 value="3fbc2e98f05854c3df16df9abaa955b91b15b3ecac33623208ed6424640ef0f6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="checker-qual-3.43.0.module">
|
||||
<sha256 value="f8163327245ab8625532948c72a930548cd97f34d6c3fe860fa6aec5a34d79b4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.codehaus.groovy" name="groovy" version="3.0.17">
|
||||
<artifact name="groovy-3.0.17.jar">
|
||||
<sha256 value="9ed2a565a8592a9f63f410afed892d0ca6bec1ff96277ce4cc7f3e2e366e794f" origin="Generated by Gradle"/>
|
||||
@ -12548,6 +12606,14 @@
|
||||
<sha256 value="de00115f1d84f3a0b2ee3a4b6f6192d066f86d185d67b9d1522f2c80feac5f00" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm" version="9.7.1">
|
||||
<artifact name="asm-9.7.1.jar">
|
||||
<sha256 value="8cadd43ac5eb6d09de05faecca38b917a040bb9139c7edeb4cc81c740b713281" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="asm-9.7.1.pom">
|
||||
<sha256 value="7229b03b30a73ee91008072d9e4569a51d8547fae8c50f527841aef4c1b0baa8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-analysis" version="9.6">
|
||||
<artifact name="asm-analysis-9.6.jar">
|
||||
<sha256 value="d92832d7c37edc07c60e2559ac6118b31d642e337a6671edcb7ba9fae68edbbb" origin="Generated by Gradle"/>
|
||||
@ -12564,6 +12630,14 @@
|
||||
<sha256 value="9c33080ebcb631ae4f77eb62ed67bfc40cb872e8cfd058ac863e445c1dd973df" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-analysis" version="9.7.1">
|
||||
<artifact name="asm-analysis-9.7.1.jar">
|
||||
<sha256 value="85b29371884ba31bb76edf22323c2c24e172c3267a67152eba3d1ccc2e041ef2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="asm-analysis-9.7.1.pom">
|
||||
<sha256 value="25c2379f2bfc2a1e64e62c39e2b93cfb0e489707852b08d6fc470b1c6a52b9ee" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-commons" version="9.6">
|
||||
<artifact name="asm-commons-9.6.jar">
|
||||
<sha256 value="7aefd0d5c0901701c69f7513feda765fb6be33af2ce7aa17c5781fc87657c511" origin="Generated by Gradle"/>
|
||||
@ -12580,6 +12654,14 @@
|
||||
<sha256 value="5acee3ee7252ed90b8074c755d022787499a95fafff98ac4a685107c4da409b4" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-commons" version="9.7.1">
|
||||
<artifact name="asm-commons-9.7.1.jar">
|
||||
<sha256 value="9a579b54d292ad9be171d4313fd4739c635592c2b5ac3a459bbd1049cddec6a0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="asm-commons-9.7.1.pom">
|
||||
<sha256 value="0bf1d31da0c9f9d8edc2f27dbbfdbbf73f1a715b72cd2fa28f3f195994d74ad1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-tree" version="9.6">
|
||||
<artifact name="asm-tree-9.6.jar">
|
||||
<sha256 value="c43ecf17b539c777e15da7b5b86553b377e2d39a683de6285567d5283888e7ef" origin="Generated by Gradle"/>
|
||||
@ -12596,6 +12678,14 @@
|
||||
<sha256 value="a34ea1e3e4128c01038db43c6976e88c779cf5af84b0505da266dfe6965668ec" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-tree" version="9.7.1">
|
||||
<artifact name="asm-tree-9.7.1.jar">
|
||||
<sha256 value="9929881f59eb6b840e86d54570c77b59ce721d104e6dfd7a40978991c2d3b41f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="asm-tree-9.7.1.pom">
|
||||
<sha256 value="13b905f65e7fd43ca7674f40cdaa37679ba4858c6c9d9fb8f17a7afd9baabc9e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-util" version="9.6">
|
||||
<artifact name="asm-util-9.6.jar">
|
||||
<sha256 value="c635a7402f4aa9bf66b2f4230cea62025a0fe1cd63e8729adefc9b1994fac4c3" origin="Generated by Gradle"/>
|
||||
@ -12612,6 +12702,14 @@
|
||||
<sha256 value="5d014d8c870d4871825bd2ddb5567b21ef6dac8ec48bbb8dbb465b0b3a2bf452" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.ow2.asm" name="asm-util" version="9.7.1">
|
||||
<artifact name="asm-util-9.7.1.jar">
|
||||
<sha256 value="f885be71b5c90556f5f1ad1c4f9276b29b96057c497d46666fe4ddbec3cb43c6" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="asm-util-9.7.1.pom">
|
||||
<sha256 value="7fb5e63362b2d52d77dca3b754aebad635751d3fc520191e9500ece9e2345b71" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.pageseeder.diffx" name="pso-diffx" version="1.1.1">
|
||||
<artifact name="pso-diffx-1.1.1.jar">
|
||||
<sha256 value="c539842b0459fe625062a5ef46cc4449c59f553110cfbdc8c99cc9903bec9690" origin="Generated by Gradle"/>
|
||||
@ -12644,6 +12742,14 @@
|
||||
<sha256 value="c422d5c8842d7a01f39b323120b87dec4725337a5b03995df03494a18f88c9a8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="annotations" version="4.14.1">
|
||||
<artifact name="annotations-4.14.1.jar">
|
||||
<sha256 value="463a5ad1386c31010bc9af00bfe19a1b758d8c2dedd8c19e5c75d29ab8abb9ba" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="annotations-4.14.1.module">
|
||||
<sha256 value="f41e24bf354432477e9022b69843513c4d5a39d722ceb73ee0a508c2889faf4f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="junit" version="4.12.2">
|
||||
<artifact name="junit-4.12.2.jar">
|
||||
<sha256 value="f3f6ebf476b4ecdffcfe4e8b3b3d6119cbe2fc59f19822d8a6c7df35dbf22c48" origin="Generated by Gradle"/>
|
||||
@ -12660,6 +12766,14 @@
|
||||
<sha256 value="a669f1f50392b26c5d510285663f2e8a870e0a7b875e862474d476147568af5f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="junit" version="4.14.1">
|
||||
<artifact name="junit-4.14.1.jar">
|
||||
<sha256 value="2cee817aadce3552706b09450ad1ea7ff5981924072d2adfe40ddad57d5fa123" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="junit-4.14.1.module">
|
||||
<sha256 value="91e77ccecdbd485c67b84c85728897df116ed3eb90f0e726f0ec79d04768c4d7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="nativeruntime" version="4.12.2">
|
||||
<artifact name="nativeruntime-4.12.2.jar">
|
||||
<sha256 value="f8e55ab954404735f5931b5179e139e158367139b7deeddf6ded7086a0467d9d" origin="Generated by Gradle"/>
|
||||
@ -12676,6 +12790,14 @@
|
||||
<sha256 value="3fcab094062f01d3a717006603f05d3ee961e843df424f0c3e4e1e6146333d64" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="nativeruntime" version="4.14.1">
|
||||
<artifact name="nativeruntime-4.14.1.jar">
|
||||
<sha256 value="c07b66d315aec3272a7c64aa5f154b4194be2cc6030a733d16f2ee87330232a8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="nativeruntime-4.14.1.module">
|
||||
<sha256 value="91b52e58cc84778086941e439659264e3804aeae45df00b47e80962ec9104da3" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="nativeruntime-dist-compat" version="1.0.10">
|
||||
<artifact name="nativeruntime-dist-compat-1.0.10.jar">
|
||||
<sha256 value="1159b8394b9d9640b53b63f07ec1fe676a7b394a90b8361eef2a88868cca3f3d" origin="Generated by Gradle"/>
|
||||
@ -12692,6 +12814,14 @@
|
||||
<sha256 value="4acdac5ceb7e1ed5574abe3510be76180316f60381501884d48cd770e82c33ef" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="nativeruntime-dist-compat" version="1.0.16">
|
||||
<artifact name="nativeruntime-dist-compat-1.0.16.jar">
|
||||
<sha256 value="2f4e879b00eed634d0e43353ecff80db4d5ce24b3b213d1e6053cb21b0ced10f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="nativeruntime-dist-compat-1.0.16.pom">
|
||||
<sha256 value="053dc5be36c03495d157186588b73952f4098cb9890f75cbd6ee26e36fd83d04" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="pluginapi" version="4.12.2">
|
||||
<artifact name="pluginapi-4.12.2.jar">
|
||||
<sha256 value="822af3ccba184421c36684ec4678e1b1b4424520891d46b1f568c10d3b036ba5" origin="Generated by Gradle"/>
|
||||
@ -12708,6 +12838,14 @@
|
||||
<sha256 value="e1e1fcded3313d9962150f1354e5ad2a8f9cdcae170dd23e608584ecba8a00a2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="pluginapi" version="4.14.1">
|
||||
<artifact name="pluginapi-4.14.1.jar">
|
||||
<sha256 value="ad8b74238d59bce6631e29190c105dd0c4701e836a2631060678407f621c7b7a" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="pluginapi-4.14.1.module">
|
||||
<sha256 value="f1be495b31fa44917a42c85437eb66ba48df2cf8b609e786a5a1694162ecf118" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="plugins-maven-dependency-resolver" version="4.12.2">
|
||||
<artifact name="plugins-maven-dependency-resolver-4.12.2.jar">
|
||||
<sha256 value="af77ec038d8c9771fed6942fc905520c80231c1aef321ede2869227e9bd8fb08" origin="Generated by Gradle"/>
|
||||
@ -12724,6 +12862,14 @@
|
||||
<sha256 value="2a6f81f13e3f8cef1b25db4f8bbe24e8fc0486ffcc5fc9b43694a6bc4cdbe8b5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="plugins-maven-dependency-resolver" version="4.14.1">
|
||||
<artifact name="plugins-maven-dependency-resolver-4.14.1.jar">
|
||||
<sha256 value="6c8dbc979db0780755e712acab9eeb9396811b2d4dc31a92a5b259f9876205ec" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="plugins-maven-dependency-resolver-4.14.1.pom">
|
||||
<sha256 value="21ab442a41f775ba7ddad9f92bbcb6d073ef4822d7c63c7d269b092890be2af0" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="resources" version="4.12.2">
|
||||
<artifact name="resources-4.12.2.jar">
|
||||
<sha256 value="7a3371613ac23070030566ac590297b301362aba8cba9372acf0f3701cfe5c99" origin="Generated by Gradle"/>
|
||||
@ -12740,6 +12886,14 @@
|
||||
<sha256 value="775f068c6b9c5134a7308bbfac5931ac3f2ac84b652577e639a88e6e1ca19cb2" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="resources" version="4.14.1">
|
||||
<artifact name="resources-4.14.1.jar">
|
||||
<sha256 value="54eb274a47dec9e74cc9b45b9e4335bb5d83857c63b2a49dd8d1993e6321f2c5" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="resources-4.14.1.module">
|
||||
<sha256 value="b2ae6c390c2ba8e0cb459106cff79f416bd5ecca1073b4c4144d58a8b1892f89" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="robolectric" version="4.12.2">
|
||||
<artifact name="robolectric-4.12.2.jar">
|
||||
<sha256 value="b8eb9d7cf85bb9636f430d68a50768d1a01a747c94b40b8e8a79abe6a3f95f82" origin="Generated by Gradle"/>
|
||||
@ -12756,6 +12910,14 @@
|
||||
<sha256 value="1c4ea47a7de2c52150082e2cf99c1fb023148316bf62d4f5919ce9afb0ca1752" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="robolectric" version="4.14.1">
|
||||
<artifact name="robolectric-4.14.1.jar">
|
||||
<sha256 value="e0a73d45bceb94a5a0352b66e2120ad4a4b222fe406079130893b6c79d4441d1" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="robolectric-4.14.1.module">
|
||||
<sha256 value="cc223907e19a2cd8d434e0981bf2d604b849d90aea182783c5c7e1a40fc6e398" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="sandbox" version="4.12.2">
|
||||
<artifact name="sandbox-4.12.2.jar">
|
||||
<sha256 value="8f0c3966ab51d0fca1ede8a4e706440d3783dbf4f6ec5c484fd3fcf0d9b9c9bf" origin="Generated by Gradle"/>
|
||||
@ -12772,6 +12934,14 @@
|
||||
<sha256 value="708a128b05c2941d16b3e1d82b4cae3da8c1f54802e79f687d7b8a72addb3fc7" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="sandbox" version="4.14.1">
|
||||
<artifact name="sandbox-4.14.1.jar">
|
||||
<sha256 value="de361f3de8c08d4488cf156683830f2bd43db1da85a5b136ad6d065b868d3bab" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="sandbox-4.14.1.module">
|
||||
<sha256 value="e1e53e16d1a8dc1675711e34108b3e0d71b6a6b7fce02e028c819a9e45b4f3cb" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="shadowapi" version="4.12.2">
|
||||
<artifact name="shadowapi-4.12.2.jar">
|
||||
<sha256 value="1918a7cfd69f82e2f125a56fa032e3828437a941ec9f077e7a3a652e84cb5cdc" origin="Generated by Gradle"/>
|
||||
@ -12788,6 +12958,14 @@
|
||||
<sha256 value="5db21aa2eb063cffa3faae654ff43603f9092d7409e1fadd784e2eed115ddbfe" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="shadowapi" version="4.14.1">
|
||||
<artifact name="shadowapi-4.14.1.jar">
|
||||
<sha256 value="fd158863cee488475206ba1d23ff4c7d29be412eccd21b12d9416b0030aa582d" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="shadowapi-4.14.1.module">
|
||||
<sha256 value="87b1fef13788f52d7bfced79ee68ef243546c5ac1ce1519274f90410fc77e637" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="shadows-framework" version="4.12.2">
|
||||
<artifact name="shadows-framework-4.12.2.jar">
|
||||
<sha256 value="907dd8bb9966ba4b83a017822449fc8ab31ab0a437b29342cb2cfca1177354e1" origin="Generated by Gradle"/>
|
||||
@ -12804,6 +12982,14 @@
|
||||
<sha256 value="bebeb74c7a6543e6d67667906bc6a3cfb0acc080ef9c8003dfd3dcd14abfb718" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="shadows-framework" version="4.14.1">
|
||||
<artifact name="shadows-framework-4.14.1.jar">
|
||||
<sha256 value="f3cf7785eecf9b2e80fbb4caac4c42f63eeea3506e289581c04696a56a494622" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="shadows-framework-4.14.1.module">
|
||||
<sha256 value="d45a50ae4255b9248d341ebe57438041451d223b8c32f6754555227281db5c46" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="shadows-versioning" version="4.12.2">
|
||||
<artifact name="shadows-versioning-4.12.2.jar">
|
||||
<sha256 value="86126b5b074cb69c6953666ae467de1fa3b6d33bf794633d5b80a1be97ff4b1a" origin="Generated by Gradle"/>
|
||||
@ -12828,6 +13014,14 @@
|
||||
<sha256 value="59d7ac54a24460c884fbb40625dad4f989bba021429d7e055e78574abf688797" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="utils" version="4.14.1">
|
||||
<artifact name="utils-4.14.1.jar">
|
||||
<sha256 value="6884eec32c9c9b23d74250e30a5ba9c5ece48784f808feba98f119b215ab59d8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="utils-4.14.1.pom">
|
||||
<sha256 value="dd438f68cdf56644fff3aff48a88561c2bd1850e74334b37de435eeed9d2a1fe" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="utils-reflector" version="4.12.2">
|
||||
<artifact name="utils-reflector-4.12.2.jar">
|
||||
<sha256 value="7e8a926d88d473a05af7cbef07941e03ddf676e987d70f40096193dba0cf5621" origin="Generated by Gradle"/>
|
||||
@ -12844,6 +13038,14 @@
|
||||
<sha256 value="5ebb1c7a2a86ad1699af0e68617513f17bb6a516d24e7936ce7d14a1d66812e8" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.robolectric" name="utils-reflector" version="4.14.1">
|
||||
<artifact name="utils-reflector-4.14.1.jar">
|
||||
<sha256 value="eb8f52cdc24f59ae4cf13369c5bf990354c19c386e3e8f9f5d5cee04d836557b" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="utils-reflector-4.14.1.module">
|
||||
<sha256 value="bd14da5907a107813fb0fa0b2c4e02c0f3958a1550f88b872ec57424a9377bb9" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.slf4j" name="slf4j-api" version="1.7.30">
|
||||
<artifact name="slf4j-api-1.7.30.jar">
|
||||
<sha256 value="cdba07964d1bb40a0761485c6b1e8c2f8fd9eb1d19c53928ac0d7f9510105c57" origin="Generated by Gradle"/>
|
||||
@ -12901,5 +13103,13 @@
|
||||
<sha256 value="ae11a3b11dcbac1b6403689e3fd8d82b2ceea55e82dbfc4bb32aededf8ccac8e" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
<component group="org.yaml" name="snakeyaml" version="2.3">
|
||||
<artifact name="snakeyaml-2.3.jar">
|
||||
<sha256 value="63a76fe66b652360bd4c2c107e6f0258daa7d4bb492008ba8c26fcd230ff9146" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
<artifact name="snakeyaml-2.3.pom">
|
||||
<sha256 value="0f5a265a06331b0049e352be32ca322de18b17f3d4dbb70635d40da692e3582f" origin="Generated by Gradle"/>
|
||||
</artifact>
|
||||
</component>
|
||||
</components>
|
||||
</verification-metadata>
|
||||
|
Loading…
Reference in New Issue
Block a user