diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4b02fb7c4..a3c114dd4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -251,7 +251,7 @@ dependencies { implementation(libs.bundles.shizuku) // Tests - testImplementation(libs.junit) + testImplementation(libs.bundles.test) // For detecting memory leaks; see https://square.github.io/leakcanary/ // debugImplementation(libs.leakcanary.android) diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index 6fc9c458e..f778082b3 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -65,7 +65,7 @@ import eu.kanade.tachiyomi.ui.manga.chapterDecimalFormat import eu.kanade.tachiyomi.util.lang.toRelativeString import eu.kanade.tachiyomi.util.system.copyToClipboard import tachiyomi.domain.chapter.model.Chapter -import tachiyomi.domain.chapter.service.countMissingChapters +import tachiyomi.domain.chapter.service.missingChaptersCount import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.source.model.StubSource import tachiyomi.presentation.core.components.LazyColumn @@ -394,7 +394,7 @@ private fun MangaScreenSmallImpl( ChapterHeader( enabled = chapters.fastAll { !it.selected }, chapterCount = chapters.size, - missingChapterCount = countMissingChapters(chapters.map { it.chapter.chapterNumber }), + missingChapterCount = chapters.map { it.chapter.chapterNumber }.missingChaptersCount(), onClick = onFilterClicked, ) } @@ -606,7 +606,7 @@ fun MangaScreenLargeImpl( ChapterHeader( enabled = chapters.fastAll { !it.selected }, chapterCount = chapters.size, - missingChapterCount = countMissingChapters(chapters.map { it.chapter.chapterNumber }), + missingChapterCount = chapters.map { it.chapter.chapterNumber }.missingChaptersCount(), onClick = onFilterButtonClicked, ) } diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/ChapterHeader.kt b/app/src/main/java/eu/kanade/presentation/manga/components/ChapterHeader.kt index 1c32c86cd..e047fb036 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/ChapterHeader.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/ChapterHeader.kt @@ -14,13 +14,13 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import eu.kanade.tachiyomi.R -import tachiyomi.presentation.core.util.secondaryItemAlpha +import tachiyomi.presentation.core.components.material.SecondaryItemAlpha @Composable fun ChapterHeader( enabled: Boolean, chapterCount: Int?, - missingChapterCount: Int?, + missingChapterCount: Int, onClick: () -> Unit, ) { Column( @@ -48,19 +48,16 @@ fun ChapterHeader( } @Composable -private fun MissingChaptersWarning(count: Int?) { - val text = when { - count == null -> stringResource(R.string.missing_chapters_unknown) - count > 0 -> pluralStringResource(id = R.plurals.missing_chapters, count = count, count) - else -> return +private fun MissingChaptersWarning(count: Int) { + if (count == 0) { + return } Text( - modifier = Modifier.secondaryItemAlpha(), - text = text, + text = pluralStringResource(id = R.plurals.missing_chapters, count = count, count), maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.bodySmall, - color = MaterialTheme.colorScheme.error, + color = MaterialTheme.colorScheme.error.copy(alpha = SecondaryItemAlpha), ) } diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index 4236ec7b8..a57db9d0b 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -21,5 +21,5 @@ dependencies { api(libs.sqldelight.android.paging) - testImplementation(libs.junit) + testImplementation(libs.bundles.test) } diff --git a/domain/src/main/java/tachiyomi/domain/chapter/service/MissingChapters.kt b/domain/src/main/java/tachiyomi/domain/chapter/service/MissingChapters.kt index 17ced5cf6..71fafe1c9 100644 --- a/domain/src/main/java/tachiyomi/domain/chapter/service/MissingChapters.kt +++ b/domain/src/main/java/tachiyomi/domain/chapter/service/MissingChapters.kt @@ -1,23 +1,21 @@ package tachiyomi.domain.chapter.service -import kotlin.math.floor - -fun countMissingChapters(chaptersInput: List): Int? { - if (chaptersInput.isEmpty()) { +fun List.missingChaptersCount(): Int { + if (this.isEmpty()) { return 0 } - val chapters = chaptersInput - // Remove any invalid chapters - .filter { it != -1f } + val chapters = this + // Ignore unknown chapter numbers + .filterNot { it == -1f } // Convert to integers, as we cannot check if 16.5 is missing - .map { floor(it.toDouble()).toInt() } + .map(Float::toInt) // Only keep unique chapters so that -1 or 16 are not counted multiple times .distinct() .sorted() if (chapters.isEmpty()) { - return null + return 0 } var missingChaptersCount = 0 diff --git a/domain/src/test/java/tachiyomi/domain/chapter/service/MissingChaptersTest.kt b/domain/src/test/java/tachiyomi/domain/chapter/service/MissingChaptersTest.kt new file mode 100644 index 000000000..4d50750c0 --- /dev/null +++ b/domain/src/test/java/tachiyomi/domain/chapter/service/MissingChaptersTest.kt @@ -0,0 +1,30 @@ +package tachiyomi.domain.chapter.service + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.parallel.Execution +import org.junit.jupiter.api.parallel.ExecutionMode + +@Execution(ExecutionMode.CONCURRENT) +class MissingChaptersTest { + + @Test + fun `returns 0 when empty list`() { + emptyList().missingChaptersCount() shouldBe 0 + } + + @Test + fun `returns 0 when all unknown chapter numbers`() { + listOf(-1f, -1f, -1f).missingChaptersCount() shouldBe 0 + } + + @Test + fun `handles repeated base chapter numbers`() { + listOf(1f, 1.0f, 1.1f, 1.5f, 1.6f, 1.99f).missingChaptersCount() shouldBe 0 + } + + @Test + fun `returns number of missing chapters`() { + listOf(-1f, 1f, 2f, 2.2f, 4f, 6f, 10f, 11f).missingChaptersCount() shouldBe 5 + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90acc0323..eaa5a9688 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -84,6 +84,7 @@ sqldelight-android-paging = { module = "com.squareup.sqldelight:android-paging3- sqldelight-gradle = { module = "com.squareup.sqldelight:gradle-plugin", version.ref = "sqldelight" } junit = "org.junit.jupiter:junit-jupiter:5.9.2" +kotest-assertions = "io.kotest:kotest-assertions-core:5.5.5" voyager-navigator = { module = "ca.gosyer:voyager-navigator", version.ref = "voyager" } voyager-tab-navigator = { module = "ca.gosyer:voyager-tab-navigator", version.ref = "voyager" } @@ -100,3 +101,4 @@ coil = ["coil-core", "coil-gif", "coil-compose"] shizuku = ["shizuku-api", "shizuku-provider"] voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"] richtext = ["richtext-commonmark", "richtext-m3"] +test = ["junit", "kotest-assertions"] \ No newline at end of file diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index 85f34d794..7e71797b3 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -617,7 +617,6 @@ Missing %1$s chapter Missing %1$s chapters - Might be missing chapters Ongoing Unknown Unknown author