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
29 changed files with 553 additions and 359 deletions
|
|
@ -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))
|
||||
}
|
||||
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))
|
||||
}
|
||||
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)
|
||||
}
|
||||
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,29 +113,27 @@ 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(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
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,22 +141,20 @@ class ViewThreadViewModelTest {
|
|||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true)
|
||||
),
|
||||
detailedStatusPosition = 0,
|
||||
revealButton = RevealButtonState.NO_BUTTON
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true)
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 0,
|
||||
revealButton = RevealButtonState.NO_BUTTON
|
||||
),
|
||||
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
|
||||
)
|
||||
}
|
||||
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,86 +182,78 @@ class ViewThreadViewModelTest {
|
|||
|
||||
viewModel.loadThread(threadId)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Error::class.java,
|
||||
viewModel.uiState.first().javaClass
|
||||
)
|
||||
}
|
||||
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(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test", isExpanded = true)
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.HIDE
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test", isExpanded = true)
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.HIDE
|
||||
),
|
||||
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)))
|
||||
eventHub.dispatch(StatusChangedEvent(fakeStatus(id = "1", spoilerText = "Test", favourited = false)))
|
||||
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test", favourited = false),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test", favourited = false),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
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(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change status expanded state`() {
|
||||
fun `should change status expanded state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
|
@ -277,24 +263,22 @@ class ViewThreadViewModelTest {
|
|||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isExpanded = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change content collapsed state`() {
|
||||
fun `should change content collapsed state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
|
@ -304,24 +288,22 @@ class ViewThreadViewModelTest {
|
|||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isCollapsed = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isCollapsed = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should change content showing state`() {
|
||||
fun `should change content showing state`() = runTest {
|
||||
mockSuccessResponses()
|
||||
|
||||
viewModel.loadThread(threadId)
|
||||
|
|
@ -331,20 +313,18 @@ class ViewThreadViewModelTest {
|
|||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test")
|
||||
)
|
||||
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isShowingContent = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
assertEquals(
|
||||
ThreadUiState.Success(
|
||||
statusViewData = listOf(
|
||||
fakeStatusViewData(id = "1", spoilerText = "Test"),
|
||||
fakeStatusViewData(id = "2", inReplyToId = "1", inReplyToAccountId = "1", isDetailed = true, spoilerText = "Test", isShowingContent = true),
|
||||
fakeStatusViewData(id = "3", inReplyToId = "2", inReplyToAccountId = "1", spoilerText = "Test")
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
detailedStatusPosition = 1,
|
||||
revealButton = RevealButtonState.REVEAL
|
||||
),
|
||||
viewModel.uiState.first()
|
||||
)
|
||||
}
|
||||
|
||||
private fun mockSuccessResponses() {
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
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,12 +64,10 @@ class TimelineCasesTest {
|
|||
)
|
||||
)
|
||||
}
|
||||
runBlocking {
|
||||
assertEquals(
|
||||
"Validation Failed: You have already pinned the maximum number of toots",
|
||||
timelineCases.pin(statusId, true).exceptionOrNull()?.message
|
||||
)
|
||||
}
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue