Skip to content

Commit

Permalink
test: unit test for normalizeForSearch
Browse files Browse the repository at this point in the history
- extract method to extension file
  • Loading branch information
criticalAY committed Feb 3, 2025
1 parent 854f4ea commit beb3226
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import com.ichi2.anki.model.CardsOrNotes.NOTES
import com.ichi2.anki.model.SortType
import com.ichi2.anki.pages.CardInfoDestination
import com.ichi2.anki.preferences.SharedPreferencesProvider
import com.ichi2.anki.utils.ext.normalizeForSearch
import com.ichi2.annotations.NeedsTest
import com.ichi2.libanki.Card
import com.ichi2.libanki.CardId
Expand Down Expand Up @@ -85,9 +86,7 @@ import java.io.DataOutputStream
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.text.Normalizer
import java.util.Collections
import java.util.regex.Pattern
import kotlin.math.max
import kotlin.math.min

Expand Down Expand Up @@ -953,11 +952,6 @@ class CardBrowserViewModel(

private suspend fun shouldIgnoreAccents() = withCol { config.getBool(ConfigKey.Bool.IGNORE_ACCENTS_IN_SEARCH) }

private fun String.normalizeForSearch(): String {
val normalized = Normalizer.normalize(this, Normalizer.Form.NFD)
return Pattern.compile("\\p{InCombiningDiacriticalMarks}+").matcher(normalized).replaceAll("")
}

/**
* @see com.ichi2.anki.searchForRows
*/
Expand Down
44 changes: 44 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/utils/ext/String.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2025 Ashish Yadav <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.ichi2.anki.utils.ext

import java.text.Normalizer
import java.util.regex.Pattern

private val DIACRITICAL_MARKS_PATTERN = Pattern.compile("\\p{InCombiningDiacriticalMarks}+")

/**
* Normalizes the given string by removing diacritical marks (accents) to enable accent-insensitive searches.
*
* This method uses Unicode normalization in **NFD (Normalization Form Decomposition)** mode, which separates
* base characters from their diacritical marks. Then, it removes all combining diacritical marks using a regex.
*
* Example usage:
* ```
* val input = "café naïve résumé"
* val normalized = input.normalizeForSearch()
* println(normalized) // Output: "cafe naive resume"
* ```
*
* @receiver The input string that may contain accented characters.
* @return A new string with accents removed.
*/
fun String.normalizeForSearch(): String {
val normalized = Normalizer.normalize(this, Normalizer.Form.NFD)
return DIACRITICAL_MARKS_PATTERN.matcher(normalized).replaceAll("")
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class PreferencesAnalyticsTest : RobolectricTest() {
R.string.hide_hard_and_easy_key, // hideHardAndEasy
R.string.reviewer_frame_style_key, // reviewerFrameStyle
R.string.hide_system_bars_key, // hideSystemBars
R.string.ignore_display_cutout_key, // ignoreDisplayCutout
R.string.ignore_display_cutout_key, // ignoreDisplayCutout,
).toStringResourceSet()

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import com.ichi2.anki.model.SortType.SORT_FIELD
import com.ichi2.anki.servicelayer.NoteService
import com.ichi2.anki.setFlagFilterSync
import com.ichi2.anki.utils.ext.ifNotZero
import com.ichi2.anki.utils.ext.normalizeForSearch
import com.ichi2.libanki.CardId
import com.ichi2.libanki.DeckId
import com.ichi2.libanki.Note
Expand All @@ -81,8 +82,11 @@ import org.hamcrest.Matchers.hasSize
import org.hamcrest.Matchers.lessThan
import org.hamcrest.Matchers.not
import org.hamcrest.Matchers.nullValue
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.jupiter.api.assertInstanceOf
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.CsvSource
import org.junit.runner.RunWith
import timber.log.Timber
import java.io.File
Expand Down Expand Up @@ -552,6 +556,21 @@ class CardBrowserViewModelTest : JvmTest() {
}
}

@ParameterizedTest
@CsvSource(
"café Ábaco naïve résumé, cafe Abaco naive resume",
"élégant déjà vu, elegant deja vu",
"hello world, hello world",
"'', ''",
"1234!@# café, 1234!@# cafe",
)
fun `test normalizeForSearch`(
input: String,
expected: String,
) {
assertEquals(expected, input.normalizeForSearch())
}

@Test
fun `suspend - notes - no selection`() =
runViewModelNotesTest(notes = 2) {
Expand Down

0 comments on commit beb3226

Please sign in to comment.