update tests and readme

This commit is contained in:
Helium314 2023-09-25 07:11:33 +02:00
parent a330e9dd17
commit cf261bf5ef
3 changed files with 68 additions and 48 deletions

View file

@ -28,9 +28,10 @@ Features that may go unnoticed
* Long-press comma to access clipboard view, emoji view, one-handed mode, settings, or switch language
* emoji view and language switch will disappear if you have the corresponding key enabled
* for some layouts it's not the comma-key, but the key at the same position (e.g. it's `q` for Dvorak layout)
* Press the incognito icon to get the toolbar (probably only hidden if you use _force incognito mode_)
* Sliding key input: swipe from shift to another key to type a single uppercase key
* also works for the `?123` key to type a single symbol from the symbols keyboard, and for related keys
* Long-press a suggestion to show more suggestions, and a delete button to remove this suggestion
* Long-press a suggestion in suggestion strip to show more suggestions, and a delete button to remove this suggestion
* Swipe up from a suggestion to open more suggestions, and release on the suggestion to select it
* You can add dictionaries by opening them in a file explorer
* only works with content-uris and not with file-uris, meaning that it may not work with some file explorers

View file

@ -61,7 +61,7 @@ class InputLogicTest {
@Test fun inputCode() {
reset()
input('c'.code)
input('c')
assertEquals("c", textBeforeCursor)
assertEquals("c", getText())
assertEquals("", textAfterCursor)
@ -91,7 +91,7 @@ class InputLogicTest {
reset()
setText("hello")
setCursorPosition(3) // after first l
input('i'.code)
input('i')
assertEquals("helilo", getWordAtCursor())
assertEquals("helilo", getText())
assertEquals(4, getCursorPosition())
@ -104,7 +104,7 @@ class InputLogicTest {
currentInputType = 180225 // should not change much, but just to be sure
setText("hello")
setCursorPosition(3, weirdTextField = true) // after first l
input('i'.code)
input('i')
assertEquals("helilo", getWordAtCursor())
assertEquals("helilo", getText())
assertEquals(4, getCursorPosition())
@ -115,7 +115,7 @@ class InputLogicTest {
reset()
setText("hello my friend")
setCursorPosition(7) // between m and y
input('a'.code)
input('a')
assertEquals("may", getWordAtCursor())
assertEquals("hello may friend", getText())
assertEquals(8, getCursorPosition())
@ -127,7 +127,7 @@ class InputLogicTest {
currentScript = ScriptUtils.SCRIPT_HANGUL
setText("ㅛㅎㄹㅎㅕㅛ")
setCursorPosition(3)
input('ㄲ'.code) // fails, as expected from the hangul issue when processing the event in onCodeInput
input('ㄲ') // fails, as expected from the hangul issue when processing the event in onCodeInput
assertEquals("ㅛㅎㄹㄲㅎㅕㅛ", getWordAtCursor())
assertEquals("ㅛㅎㄹㄲㅎㅕㅛ", getText())
assertEquals("ㅛㅎㄹㄲㅎㅕㅛ", textBeforeCursor + textAfterCursor)
@ -139,7 +139,7 @@ class InputLogicTest {
reset()
setText("hello")
assertEquals("hello", composingText)
input('.'.code)
input('.')
assertEquals("", composingText)
}
@ -147,13 +147,13 @@ class InputLogicTest {
@Test fun autospace() {
reset()
setText("hello")
input('.'.code)
input('a'.code)
input('.')
input('a')
assertEquals("hello.a", textBeforeCursor)
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) }
setText("hello")
input('.'.code)
input('a'.code)
input('.')
input('a')
assertEquals("hello. a", textBeforeCursor)
}
@ -161,15 +161,15 @@ class InputLogicTest {
reset()
setText("hello there")
setCursorPosition(5) // after hello
input('.'.code)
input('a'.code)
input('.')
input('a')
assertEquals("hello.a", textBeforeCursor)
assertEquals("hello.a there", text)
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) }
setText("hello there")
setCursorPosition(5) // after hello
input('.'.code)
input('a'.code)
input('.')
input('a')
assertEquals("hello. a", textBeforeCursor)
assertEquals("hello. a there", text)
}
@ -177,33 +177,33 @@ class InputLogicTest {
@Test fun urlDetectionThings() {
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
input('.'.code)
input('.'.code)
input('.'.code)
input('h'.code)
input('.')
input('.')
input('.')
input('h')
assertEquals("...h", text)
assertEquals("h", composingText)
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
input("bla")
input('.'.code)
input('.'.code)
input('.')
input('.')
assertEquals("bla..", text)
assertEquals("", composingText)
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
input("bla")
input('.'.code)
input('c'.code)
input('.')
input('c')
assertEquals("bla.c", text)
assertEquals("bla.c", composingText)
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) }
input("bla")
input('.'.code)
input('.')
functionalKeyPress(Constants.CODE_SHIFT) // should remove the phantom space (in addition to normal effect)
input('c'.code)
input('c')
assertEquals("bla.c", text)
assertEquals("bla.c", composingText)
}
@ -212,10 +212,10 @@ class InputLogicTest {
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
setText("example.co")
input('m'.code)
input('.'.code)
input('m')
input('.')
assertEquals("example.com.", composingText)
input(' '.code)
input(' ')
assertEquals("example.com", ShadowFacilitator2.lastAddedWord)
}
@ -223,9 +223,9 @@ class InputLogicTest {
reset()
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
setText("bl")
input('a'.code)
input('.'.code)
input('.'.code)
input('a')
input('.')
input('.')
assertEquals("", composingText)
assertEquals("bla..", text)
}
@ -237,6 +237,18 @@ class InputLogicTest {
assertEquals("s is ", text.substring(3, 8))
}
@Test fun noComposingForPasswordFields() {
reset()
setInputType(InputType.TYPE_CLASS_TEXT and InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD)
input('a')
input('b')
assertEquals("", composingText)
DeviceProtectedUtils.getSharedPreferences(latinIME).edit { putBoolean(Settings.PREF_URL_DETECTION, true) }
input('.')
input('c')
assertEquals("", composingText)
}
// ------- helper functions ---------
// should be called before every test, so the same state is guaranteed
@ -258,6 +270,7 @@ class InputLogicTest {
setText("")
}
private fun input(char: Char) = input(char.code)
private fun input(codePoint: Int) {
val oldBefore = textBeforeCursor
val oldAfter = textAfterCursor
@ -373,6 +386,12 @@ class InputLogicTest {
private fun getText() =
connection.getTextBeforeCursor(100, 0).toString() + (connection.getSelectedText(0) ?: "") + connection.getTextAfterCursor(100, 0)
private fun setInputType(inputType: Int) {
// set text to actually apply input type
currentInputType = inputType
setText(text)
}
// always need to handle messages for proper simulation
private fun handleMessages() {
while (messages.isNotEmpty()) {
@ -608,4 +627,4 @@ class ShadowFacilitator2 {
companion object {
var lastAddedWord = ""
}
}
}

View file

@ -1,7 +1,6 @@
package org.dslul.openboard.inputmethod.latin
import androidx.core.content.edit
import androidx.test.runner.AndroidJUnit4
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo.KIND_FLAG_APPROPRIATE_FOR_AUTO_CORRECTION
import org.dslul.openboard.inputmethod.latin.SuggestedWords.SuggestedWordInfo.KIND_WHITELIST
@ -15,13 +14,14 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.Implementation
import org.robolectric.annotation.Implements
import org.robolectric.shadows.ShadowLog
import java.util.*
@RunWith(AndroidJUnit4::class)
@RunWith(RobolectricTestRunner::class)
@Config(shadows = [
ShadowLocaleManagerCompat::class,
ShadowInputMethodManager2::class,
@ -46,7 +46,7 @@ class SuggestTest {
.edit { putBoolean(Settings.PREF_AUTO_CORRECTION, true) } // need to enable, off by default
}
@Test fun `"on" to "in" if "in" was used before in this context`() {
@Test fun `'on' to 'in' if 'in' was used before in this context`() {
val locale = Locale.ENGLISH
val result = shouldBeAutoCorrected(
"on",
@ -60,7 +60,7 @@ class SuggestTest {
// not corrected because first suggestion score is too low
}
@Test fun `"ill" to "I'll" if "ill" not used before in this context, and I'll has shortcut`() {
@Test fun `'ill' to 'I'll' if 'ill' not used before in this context, and I'll has shortcut`() {
val locale = Locale.ENGLISH
val result = shouldBeAutoCorrected(
"ill",
@ -74,7 +74,7 @@ class SuggestTest {
// correction because both empty scores are 0, which should be fine (next check is comparing empty scores)
}
@Test fun `not "ill" to "I'll" if only "ill" was used before in this context`() {
@Test fun `not 'ill' to 'I'll' if only 'ill' was used before in this context`() {
val locale = Locale.ENGLISH
val result = shouldBeAutoCorrected(
"ill",
@ -88,7 +88,7 @@ class SuggestTest {
// not corrected because first empty score not high enough
}
@Test fun `"ill" to "I'll" if both have same ngram score`() {
@Test fun `'ill' to 'I'll' if both have same ngram score`() {
val locale = Locale.ENGLISH
val result = shouldBeAutoCorrected(
"ill",
@ -101,7 +101,7 @@ class SuggestTest {
assert(result.last()) // should be corrected
}
@Test fun `no "ill" to "I'll" if "ill" has somewhat better ngram score`() {
@Test fun `no 'ill' to 'I'll' if 'ill' has somewhat better ngram score`() {
val locale = Locale.ENGLISH
val result = shouldBeAutoCorrected(
"ill",
@ -114,7 +114,7 @@ class SuggestTest {
assert(!result.last()) // should not be corrected
}
@Test fun `no English "I" for Polish "i" when typing in Polish`() {
@Test fun `no English 'I' for Polish 'i' when typing in Polish`() {
val result = shouldBeAutoCorrected(
"i",
listOf(suggestion("I", Int.MAX_VALUE, Locale.ENGLISH), suggestion("i", 1500000, Locale("pl"))),
@ -128,7 +128,7 @@ class SuggestTest {
// if very aggressive, still no correction because locale matches with typed word only
}
@Test fun `English "I" instead of Polish "i" when typing in English`() {
@Test fun `English 'I' instead of Polish 'i' when typing in English`() {
val result = shouldBeAutoCorrected(
"i",
listOf(suggestion("I", Int.MAX_VALUE, Locale.ENGLISH), suggestion("i", 1500000, Locale("pl"))),
@ -144,7 +144,7 @@ class SuggestTest {
// todo: consider special score for case-only difference?
}
@Test fun `no English "in" instead of French "un" when typing in French`() {
@Test fun `no English 'in' instead of French 'un' when typing in French`() {
val result = shouldBeAutoCorrected(
"un",
listOf(suggestion("in", Int.MAX_VALUE, Locale.ENGLISH), suggestion("un", 1500000, Locale.FRENCH)),
@ -157,7 +157,7 @@ class SuggestTest {
// not corrected because of locale matching
}
@Test fun `no "né" instead of "ne"`() {
@Test fun `no 'né' instead of 'ne'`() {
val result = shouldBeAutoCorrected(
"ne",
listOf(suggestion("ne", 1900000, Locale.FRENCH), suggestion("", 1900000-1, Locale.FRENCH)),
@ -170,7 +170,7 @@ class SuggestTest {
// not corrected because score is lower
}
@Test fun `"né" instead of "ne" if "né" in ngram context`() {
@Test fun `'né' instead of 'ne' if 'né' in ngram context`() {
val locale = Locale.FRENCH
val result = shouldBeAutoCorrected(
"ne",
@ -183,7 +183,7 @@ class SuggestTest {
assert(result.last()) // should be corrected
}
@Test fun `"né" instead of "ne" if "né" has clearly better score in ngram context`() {
@Test fun `'né' instead of 'ne' if 'né' has clearly better score in ngram context`() {
val locale = Locale.FRENCH
val result = shouldBeAutoCorrected(
"ne",
@ -196,7 +196,7 @@ class SuggestTest {
assert(result.last()) // should be corrected
}
@Test fun `no "né" instead of "ne" if both with same score in ngram context`() {
@Test fun `no 'né' instead of 'ne' if both with same score in ngram context`() {
val locale = Locale.FRENCH
val result = shouldBeAutoCorrected(
"ne",
@ -209,7 +209,7 @@ class SuggestTest {
assert(!result.last()) // should not be corrected
}
@Test fun `no "ne" instead of "né"`() {
@Test fun `no 'ne' instead of 'né'`() {
val locale = Locale.FRENCH
val result = shouldBeAutoCorrected(
"",
@ -298,7 +298,7 @@ fun suggestion(word: String, score: Int, locale: Locale) =
@Implements(DictionaryFacilitatorImpl::class)
class ShadowFacilitator {
@Implementation
fun getCurrentLocale() = currentTypingLocale
fun getCurrentLocale(): Locale = currentTypingLocale
@Implementation
fun hasAtLeastOneInitializedMainDictionary() = true // otherwise no autocorrect
}