Add tests for MissingChapters function

This commit is contained in:
arkon 2023-04-15 09:51:52 -04:00
parent 4bcd623829
commit 8ab7e63293
8 changed files with 51 additions and 25 deletions

View file

@ -251,7 +251,7 @@ dependencies {
implementation(libs.bundles.shizuku) implementation(libs.bundles.shizuku)
// Tests // Tests
testImplementation(libs.junit) testImplementation(libs.bundles.test)
// For detecting memory leaks; see https://square.github.io/leakcanary/ // For detecting memory leaks; see https://square.github.io/leakcanary/
// debugImplementation(libs.leakcanary.android) // debugImplementation(libs.leakcanary.android)

View file

@ -65,7 +65,7 @@ import eu.kanade.tachiyomi.ui.manga.chapterDecimalFormat
import eu.kanade.tachiyomi.util.lang.toRelativeString import eu.kanade.tachiyomi.util.lang.toRelativeString
import eu.kanade.tachiyomi.util.system.copyToClipboard import eu.kanade.tachiyomi.util.system.copyToClipboard
import tachiyomi.domain.chapter.model.Chapter 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.manga.model.Manga
import tachiyomi.domain.source.model.StubSource import tachiyomi.domain.source.model.StubSource
import tachiyomi.presentation.core.components.LazyColumn import tachiyomi.presentation.core.components.LazyColumn
@ -394,7 +394,7 @@ private fun MangaScreenSmallImpl(
ChapterHeader( ChapterHeader(
enabled = chapters.fastAll { !it.selected }, enabled = chapters.fastAll { !it.selected },
chapterCount = chapters.size, chapterCount = chapters.size,
missingChapterCount = countMissingChapters(chapters.map { it.chapter.chapterNumber }), missingChapterCount = chapters.map { it.chapter.chapterNumber }.missingChaptersCount(),
onClick = onFilterClicked, onClick = onFilterClicked,
) )
} }
@ -606,7 +606,7 @@ fun MangaScreenLargeImpl(
ChapterHeader( ChapterHeader(
enabled = chapters.fastAll { !it.selected }, enabled = chapters.fastAll { !it.selected },
chapterCount = chapters.size, chapterCount = chapters.size,
missingChapterCount = countMissingChapters(chapters.map { it.chapter.chapterNumber }), missingChapterCount = chapters.map { it.chapter.chapterNumber }.missingChaptersCount(),
onClick = onFilterButtonClicked, onClick = onFilterButtonClicked,
) )
} }

View file

@ -14,13 +14,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.util.secondaryItemAlpha import tachiyomi.presentation.core.components.material.SecondaryItemAlpha
@Composable @Composable
fun ChapterHeader( fun ChapterHeader(
enabled: Boolean, enabled: Boolean,
chapterCount: Int?, chapterCount: Int?,
missingChapterCount: Int?, missingChapterCount: Int,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
Column( Column(
@ -48,19 +48,16 @@ fun ChapterHeader(
} }
@Composable @Composable
private fun MissingChaptersWarning(count: Int?) { private fun MissingChaptersWarning(count: Int) {
val text = when { if (count == 0) {
count == null -> stringResource(R.string.missing_chapters_unknown) return
count > 0 -> pluralStringResource(id = R.plurals.missing_chapters, count = count, count)
else -> return
} }
Text( Text(
modifier = Modifier.secondaryItemAlpha(), text = pluralStringResource(id = R.plurals.missing_chapters, count = count, count),
text = text,
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.error, color = MaterialTheme.colorScheme.error.copy(alpha = SecondaryItemAlpha),
) )
} }

View file

@ -21,5 +21,5 @@ dependencies {
api(libs.sqldelight.android.paging) api(libs.sqldelight.android.paging)
testImplementation(libs.junit) testImplementation(libs.bundles.test)
} }

View file

@ -1,23 +1,21 @@
package tachiyomi.domain.chapter.service package tachiyomi.domain.chapter.service
import kotlin.math.floor fun List<Float>.missingChaptersCount(): Int {
if (this.isEmpty()) {
fun countMissingChapters(chaptersInput: List<Float>): Int? {
if (chaptersInput.isEmpty()) {
return 0 return 0
} }
val chapters = chaptersInput val chapters = this
// Remove any invalid chapters // Ignore unknown chapter numbers
.filter { it != -1f } .filterNot { it == -1f }
// Convert to integers, as we cannot check if 16.5 is missing // 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 // Only keep unique chapters so that -1 or 16 are not counted multiple times
.distinct() .distinct()
.sorted() .sorted()
if (chapters.isEmpty()) { if (chapters.isEmpty()) {
return null return 0
} }
var missingChaptersCount = 0 var missingChaptersCount = 0

View file

@ -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<Float>().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
}
}

View file

@ -84,6 +84,7 @@ sqldelight-android-paging = { module = "com.squareup.sqldelight:android-paging3-
sqldelight-gradle = { module = "com.squareup.sqldelight:gradle-plugin", version.ref = "sqldelight" } sqldelight-gradle = { module = "com.squareup.sqldelight:gradle-plugin", version.ref = "sqldelight" }
junit = "org.junit.jupiter:junit-jupiter:5.9.2" 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-navigator = { module = "ca.gosyer:voyager-navigator", version.ref = "voyager" }
voyager-tab-navigator = { module = "ca.gosyer:voyager-tab-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"] shizuku = ["shizuku-api", "shizuku-provider"]
voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"] voyager = ["voyager-navigator", "voyager-tab-navigator", "voyager-transitions"]
richtext = ["richtext-commonmark", "richtext-m3"] richtext = ["richtext-commonmark", "richtext-m3"]
test = ["junit", "kotest-assertions"]

View file

@ -617,7 +617,6 @@
<item quantity="one">Missing %1$s chapter</item> <item quantity="one">Missing %1$s chapter</item>
<item quantity="other">Missing %1$s chapters</item> <item quantity="other">Missing %1$s chapters</item>
</plurals> </plurals>
<string name="missing_chapters_unknown">Might be missing chapters</string>
<string name="ongoing">Ongoing</string> <string name="ongoing">Ongoing</string>
<string name="unknown">Unknown</string> <string name="unknown">Unknown</string>
<string name="unknown_author">Unknown author</string> <string name="unknown_author">Unknown author</string>