Skip to content

Commit

Permalink
[fix|test] Fix crash caused by unsaveable PictureInPictureParams.Buil…
Browse files Browse the repository at this point in the history
…der; add test code
  • Loading branch information
SkyD666 committed Dec 11, 2024
1 parent 5a15e27 commit 869c53f
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 14 deletions.
6 changes: 5 additions & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ android {
minSdk = 24
targetSdk = 35
versionCode = 24
versionName = "2.1-beta16"
versionName = "2.1-beta17"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -183,6 +183,7 @@ dependencies {
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.ktx)
implementation(libs.androidx.room.paging)
implementation(libs.androidx.junit.ktx)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.androidx.datastore.preferences)
Expand Down Expand Up @@ -237,6 +238,9 @@ dependencies {

// debugImplementation("com.squareup.leakcanary:leakcanary-android:2.13")
testImplementation(libs.junit)
testImplementation(libs.mockito.core)
testImplementation(libs.mockito.kotlin)
androidTestImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
126 changes: 126 additions & 0 deletions app/src/androidTest/java/com/skyd/anivu/RssModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.skyd.anivu

import android.content.Context
import androidx.paging.PagingConfig
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.skyd.anivu.base.mvi.mviViewModelNeedMainThread
import com.skyd.anivu.config.Const
import com.skyd.anivu.model.bean.group.GroupVo
import com.skyd.anivu.model.db.AppDatabase
import com.skyd.anivu.model.db.dao.ArticleDao
import com.skyd.anivu.model.db.dao.FeedDao
import com.skyd.anivu.model.db.dao.GroupDao
import com.skyd.anivu.model.repository.ArticleRepository
import com.skyd.anivu.model.repository.ReadRepository
import com.skyd.anivu.model.repository.RssHelper
import com.skyd.anivu.model.repository.SearchRepository
import com.skyd.anivu.model.repository.feed.FeedRepository
import com.skyd.anivu.model.repository.feed.ReorderGroupRepository
import com.skyd.anivu.model.repository.feed.RequestHeadersRepository
import com.skyd.anivu.util.favicon.FaviconExtractor
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import org.junit.After
import org.junit.Assert.*
import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import retrofit2.Retrofit
import java.io.IOException


/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(AndroidJUnit4::class)
class RssModule {
private val json = Json {
ignoreUnknownKeys = true
explicitNulls = false
}

private val okHttpClient: OkHttpClient = OkHttpClient.Builder()
.addInterceptor(HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
})
.build()

private val retrofit = Retrofit
.Builder()
.baseUrl(Const.BASE_URL)
.addConverterFactory(json.asConverterFactory("application/json".toMediaType()))
.client(okHttpClient)
.build()

private val faviconExtractor = FaviconExtractor(retrofit)
private val pagingConfig = PagingConfig(pageSize = 20, enablePlaceholders = false)

private lateinit var db: AppDatabase
private lateinit var groupDao: GroupDao
private lateinit var feedDao: FeedDao
private lateinit var articleDao: ArticleDao
private var rssHelper: RssHelper = RssHelper(okHttpClient, faviconExtractor)
private lateinit var reorderGroupRepository: ReorderGroupRepository
private lateinit var feedRepository: FeedRepository
private lateinit var articleRepository: ArticleRepository
private lateinit var readRepository: ReadRepository
private lateinit var searchRepository: SearchRepository
private lateinit var requestHeadersRepository: RequestHeadersRepository


@Test
fun test1RequestGroupAnyList() = runTest {
feedRepository.requestGroupAnyList().first().also {
assertTrue(it[0] is GroupVo.DefaultGroup)
}
}

@Test
fun test2SetFeed() = runTest {
feedRepository.setFeed(
url = "https://blogs.nvidia.cn/feed/",
groupId = null,
nickname = "Nvidia",
).first().also {
assertTrue(
it.url == "https://blogs.nvidia.cn/feed/" &&
it.groupId == null && it.nickname == "Nvidia"
)
}
}

@Before
fun init() {
mviViewModelNeedMainThread = false

val context = ApplicationProvider.getApplicationContext<Context>()
db = AppDatabase.getInstance(context)
groupDao = db.groupDao()
feedDao = db.feedDao()
articleDao = db.articleDao()

reorderGroupRepository = ReorderGroupRepository(groupDao)
feedRepository =
FeedRepository(groupDao, feedDao, articleDao, reorderGroupRepository, rssHelper)
articleRepository = ArticleRepository(feedDao, articleDao, rssHelper, pagingConfig)
searchRepository = SearchRepository(feedDao, articleDao, pagingConfig)
requestHeadersRepository = RequestHeadersRepository(feedDao)
}

@After
@Throws(IOException::class)
fun destroy() {
// db.close()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,18 @@ import java.util.concurrent.atomic.AtomicInteger
import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.coroutines.ContinuationInterceptor

var mviViewModelNeedMainThread: Boolean = BuildConfig.DEBUG

private fun debugCheckMainThread() {
if (BuildConfig.DEBUG) {
if (mviViewModelNeedMainThread) {
check(Looper.getMainLooper() === Looper.myLooper()) {
"Expected to be called on the main thread but was " + Thread.currentThread().name
}
}
}

suspend fun debugCheckImmediateMainDispatcher() {
if (BuildConfig.DEBUG) {
if (mviViewModelNeedMainThread) {
val interceptor = currentCoroutineContext()[ContinuationInterceptor]
Log.d(
"###",
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/skyd/anivu/model/db/dao/ArticleDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import androidx.room.RewriteQueriesToDropUnusedColumns
import androidx.room.Transaction
import androidx.sqlite.db.SupportSQLiteQuery
import com.skyd.anivu.appContext
import com.skyd.anivu.model.bean.feed.FEED_TABLE_NAME
import com.skyd.anivu.model.bean.feed.FeedBean
import com.skyd.anivu.model.bean.article.ARTICLE_TABLE_NAME
import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.article.ArticleWithEnclosureBean
import com.skyd.anivu.model.bean.article.ArticleWithFeed
import com.skyd.anivu.model.bean.article.EnclosureBean
import com.skyd.anivu.model.bean.feed.FEED_TABLE_NAME
import com.skyd.anivu.model.bean.feed.FeedBean
import com.skyd.anivu.ui.notification.ArticleNotificationManager
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/com/skyd/anivu/model/db/dao/FeedDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import androidx.room.Transaction
import androidx.room.Update
import androidx.sqlite.db.SupportSQLiteQuery
import com.skyd.anivu.appContext
import com.skyd.anivu.model.bean.article.ArticleBean
import com.skyd.anivu.model.bean.feed.FEED_TABLE_NAME
import com.skyd.anivu.model.bean.feed.FEED_VIEW_NAME
import com.skyd.anivu.model.bean.feed.FeedBean
import com.skyd.anivu.model.bean.feed.FeedViewBean
import com.skyd.anivu.model.bean.feed.FeedWithArticleBean
import com.skyd.anivu.model.bean.group.GROUP_TABLE_NAME
import com.skyd.anivu.model.bean.group.GroupBean
import com.skyd.anivu.model.bean.article.ArticleBean
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.android.EntryPointAccessors
Expand Down Expand Up @@ -56,7 +56,7 @@ interface FeedDao {
val articleId = articleWithEnclosure.article.articleId

// Add ArticleWithEnclosure
if (articleWithEnclosure.article.feedUrl != feedUrl) {
return@map if (articleWithEnclosure.article.feedUrl != feedUrl) {
articleWithEnclosure.copy(
article = articleWithEnclosure.article.copy(feedUrl = feedUrl),
enclosures = articleWithEnclosure.enclosures.map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ class FeedRepository @Inject constructor(
.flowOn(Dispatchers.IO)
}

suspend fun setFeed(feedBean: FeedBean): Flow<Unit> {
return flowOf(feedDao.setFeed(feedBean))
.flowOn(Dispatchers.IO)
}

suspend fun setFeed(
url: String,
groupId: String?,
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/skyd/anivu/ui/mpv/pip/PipUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toAndroidRectF
Expand Down Expand Up @@ -60,7 +59,7 @@ internal fun Modifier.pipParams(
shouldEnterPipMode: Boolean,
playState: PlayState,
): Modifier = run {
var builder by rememberSaveable { mutableStateOf<PictureInPictureParams.Builder?>(null) }
var builder by remember { mutableStateOf<PictureInPictureParams.Builder?>(null) }
val currentPlayState by rememberUpdatedState(playState)
val setActionsAndApplyBuilder: (PictureInPictureParams.Builder) -> Unit = remember {
{ builder ->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.skyd.anivu.ui.screen.feed

import android.util.Log
import com.skyd.anivu.base.mvi.AbstractMviViewModel
import com.skyd.anivu.ext.catchMap
import com.skyd.anivu.ext.startWith
Expand Down
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,13 @@ libtorrent4j-x8664 = { module = "org.libtorrent4j:libtorrent4j-android-x86_64",

junit = { module = "junit:junit", version = "4.13.2" }
androidx-junit = { module = "androidx.test.ext:junit", version = "1.2.1" }
androidx-junit-ktx = { group = "androidx.test.ext", name = "junit-ktx", version = "1.2.1" }
mockito-core = { module = "org.mockito:mockito-core", version = "5.14.2" }
mockito-kotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "5.4.0" }
androidx-espresso-core = { module = "androidx.test.espresso:espresso-core", version = "3.6.1" }
androidx-uiautomator = { group = "androidx.test.uiautomator", name = "uiautomator", version = "2.3.0" }
androidx-benchmark-macro-junit4 = { group = "androidx.benchmark", name = "benchmark-macro-junit4", version = "1.3.3" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version = "1.9.0" }

[plugins]
android-application = { id = "com.android.application", version = "8.7.3" }
Expand Down

0 comments on commit 869c53f

Please sign in to comment.