diff --git a/android/build.gradle b/android/build.gradle index b4030398..c7033c25 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -73,6 +73,8 @@ dependencies { implementation 'com.github.MikeOrtiz:TouchImageView:3.6' // Testing + testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.6.1' androidTestImplementation "androidx.test:core:1.6.1" diff --git a/android/src/main/kotlin/org/ligi/survivalmanual/functions/Search.kt b/android/src/main/kotlin/org/ligi/survivalmanual/functions/Search.kt index 29b68630..80a508bc 100644 --- a/android/src/main/kotlin/org/ligi/survivalmanual/functions/Search.kt +++ b/android/src/main/kotlin/org/ligi/survivalmanual/functions/Search.kt @@ -9,9 +9,22 @@ private const val EXCERPT_SIZE = 100 @VisibleForTesting fun getExcerpt(text: String, term: String): String { - val index = text.indexOf(term) - val rough = text.substring(max(index - EXCERPT_SIZE, 0)..(index + EXCERPT_SIZE).coerceAtMost(text.lastIndex)) - return rough.substring(rough.indexOf(" ")..rough.lastIndexOf(" ")) + val index = text.indexOf(term, ignoreCase = true) + if (index == -1) { + return text.take(EXCERPT_SIZE * 2).trim() + } + + val startBound = max(index - EXCERPT_SIZE, 0) + val endBound = (index + term.length + EXCERPT_SIZE).coerceAtMost(text.length) + + val excerptStart = text.lastIndexOf(' ', startBound).takeIf { it >= 0 }?.plus(1) ?: startBound + val excerptEnd = text.indexOf(' ', endBound).takeIf { it >= 0 } ?: endBound + + if (excerptEnd > excerptStart) { + return text.substring(excerptStart, excerptEnd).trim() + } + + return text.substring(startBound, endBound).trim() } interface Search { diff --git a/android/src/test/java/org/ligi/survivalmanual/functions/SearchTest.kt b/android/src/test/java/org/ligi/survivalmanual/functions/SearchTest.kt new file mode 100644 index 00000000..45373376 --- /dev/null +++ b/android/src/test/java/org/ligi/survivalmanual/functions/SearchTest.kt @@ -0,0 +1,27 @@ +package org.ligi.survivalmanual.functions + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +class SearchTest { + @Test + fun `excerpt uses case insensitive matches`() { + val text = "This is a Sample text about survival readiness." + val term = "sample" + + val excerpt = getExcerpt(text, term) + + assertTrue(excerpt.contains("Sample", ignoreCase = false), "Excerpt should contain the original casing of the match") + } + + @Test + fun `excerpt handles text without spaces`() { + val text = "SurvivalManual" + val term = "manual" + + val excerpt = getExcerpt(text, term) + + assertEquals(text, excerpt, "Excerpt should fall back to the available text when no spaces are present") + } +}