Skip to content

Commit

Permalink
update tests and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
Helium314 committed Sep 25, 2023
1 parent a330e9d commit cf261bf
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 48 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class InputLogicTest {

@Test fun inputCode() {
reset()
input('c'.code)
input('c')
assertEquals("c", textBeforeCursor)
assertEquals("c", getText())
assertEquals("", textAfterCursor)
Expand Down Expand Up @@ -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())
Expand All @@ -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())
Expand All @@ -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())
Expand All @@ -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)
Expand All @@ -139,71 +139,71 @@ class InputLogicTest {
reset()
setText("hello")
assertEquals("hello", composingText)
input('.'.code)
input('.')
assertEquals("", composingText)
}

// todo: try the same if there is text afterwards (not touching)
@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)
}

@Test fun autospaceButWithTextAfter() {
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)
}

@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)
}
Expand All @@ -212,20 +212,20 @@ 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)
}

@Test fun dontSelectConsecutiveSeparatorsWithURLDetection() {
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)
}
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -608,4 +627,4 @@ class ShadowFacilitator2 {
companion object {
var lastAddedWord = ""
}
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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,
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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"))),
Expand All @@ -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"))),
Expand All @@ -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)),
Expand All @@ -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)),
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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",
Expand All @@ -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(
"",
Expand Down Expand Up @@ -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
}
Expand Down

0 comments on commit cf261bf

Please sign in to comment.