mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-20 22:29:10 +00:00
update tests and readme
This commit is contained in:
parent
a330e9dd17
commit
cf261bf5ef
3 changed files with 68 additions and 48 deletions
|
@ -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
|
||||
|
|
|
@ -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 = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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("né", 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(
|
||||
"né",
|
||||
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue