aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java92
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java122
-rw-r--r--java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java2
-rw-r--r--tests/res/values/donottranslate.xml18
-rw-r--r--tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java6
-rw-r--r--tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java102
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java200
-rw-r--r--tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java284
-rw-r--r--tools/make-keyboard-text/res/values-hi-rZZ/donottranslate-more-keys.xml8
-rw-r--r--tools/make-keyboard-text/res/values/donottranslate-more-keys.xml8
10 files changed, 547 insertions, 295 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
index cd6abeed3..f9297ac27 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java
@@ -25,49 +25,42 @@ import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
-import java.util.HashMap;
import java.util.Locale;
+// TODO: Make this an immutable class.
public final class KeyboardTextsSet {
public static final String PREFIX_TEXT = "!text/";
+ private static final String PREFIX_RESOURCE = "!string/";
public static final String SWITCH_TO_ALPHA_KEY_LABEL = "keylabel_to_alpha";
private static final char BACKSLASH = Constants.CODE_BACKSLASH;
- private static final int MAX_STRING_REFERENCE_INDIRECTION = 10;
+ private static final int MAX_REFERENCE_INDIRECTION = 10;
+ private Resources mResources;
+ private Locale mResourceLocale;
+ private String mResourcePackageName;
private String[] mTextsTable;
- // Resource name to text map.
- private HashMap<String, String> mResourceNameToTextsMap = new HashMap<>();
public void setLocale(final Locale locale, final Context context) {
- mTextsTable = KeyboardTextsTable.getTextsTable(locale);
final Resources res = context.getResources();
- final int referenceId = context.getApplicationInfo().labelRes;
- final String resourcePackageName = res.getResourcePackageName(referenceId);
- final RunInLocale<Void> job = new RunInLocale<Void>() {
- @Override
- protected Void job(final Resources resource) {
- loadStringResourcesInternal(res, RESOURCE_NAMES, resourcePackageName);
- return null;
- }
- };
// Null means the current system locale.
- job.runInLocale(res,
- SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale);
+ final String resourcePackageName = res.getResourcePackageName(
+ context.getApplicationInfo().labelRes);
+ setLocale(locale, res, resourcePackageName);
}
@UsedForTesting
- void loadStringResourcesInternal(final Resources res, final String[] resourceNames,
+ public void setLocale(final Locale locale, final Resources res,
final String resourcePackageName) {
- for (final String resName : resourceNames) {
- final int resId = res.getIdentifier(resName, "string", resourcePackageName);
- mResourceNameToTextsMap.put(resName, res.getString(resId));
- }
+ mResources = res;
+ // Null means the current system locale.
+ mResourceLocale = SubtypeLocaleUtils.NO_LANGUAGE.equals(locale.toString()) ? null : locale;
+ mResourcePackageName = resourcePackageName;
+ mTextsTable = KeyboardTextsTable.getTextsTable(locale);
}
public String getText(final String name) {
- final String text = mResourceNameToTextsMap.get(name);
- return (text != null) ? text : KeyboardTextsTable.getText(name, mTextsTable);
+ return KeyboardTextsTable.getText(name, mTextsTable);
}
private static int searchTextNameEnd(final String text, final int start) {
@@ -93,13 +86,14 @@ public final class KeyboardTextsSet {
StringBuilder sb;
do {
level++;
- if (level >= MAX_STRING_REFERENCE_INDIRECTION) {
- throw new RuntimeException("Too many " + PREFIX_TEXT + "name indirection: " + text);
+ if (level >= MAX_REFERENCE_INDIRECTION) {
+ throw new RuntimeException("Too many " + PREFIX_TEXT + " or " + PREFIX_RESOURCE +
+ " reference indirection: " + text);
}
- final int prefixLen = PREFIX_TEXT.length();
+ final int prefixLength = PREFIX_TEXT.length();
final int size = text.length();
- if (size < prefixLen) {
+ if (size < prefixLength) {
break;
}
@@ -110,10 +104,12 @@ public final class KeyboardTextsSet {
if (sb == null) {
sb = new StringBuilder(text.substring(0, pos));
}
- final int end = searchTextNameEnd(text, pos + prefixLen);
- final String name = text.substring(pos + prefixLen, end);
- sb.append(getText(name));
- pos = end - 1;
+ pos = expandReference(text, pos, PREFIX_TEXT, sb);
+ } else if (text.startsWith(PREFIX_RESOURCE, pos)) {
+ if (sb == null) {
+ sb = new StringBuilder(text.substring(0, pos));
+ }
+ pos = expandReference(text, pos, PREFIX_RESOURCE, sb);
} else if (c == BACKSLASH) {
if (sb != null) {
// Append both escape character and escaped character.
@@ -132,18 +128,24 @@ public final class KeyboardTextsSet {
return TextUtils.isEmpty(text) ? null : text;
}
- // These texts' name should be aligned with the @string/<name> in
- // values*/strings-action-keys.xml.
- static final String[] RESOURCE_NAMES = {
- // Labels for action.
- "label_go_key",
- "label_send_key",
- "label_next_key",
- "label_done_key",
- "label_search_key",
- "label_previous_key",
- // Other labels.
- "label_pause_key",
- "label_wait_key",
- };
+ private int expandReference(final String text, final int pos, final String prefix,
+ final StringBuilder sb) {
+ final int prefixLength = prefix.length();
+ final int end = searchTextNameEnd(text, pos + prefixLength);
+ final String name = text.substring(pos + prefixLength, end);
+ if (prefix.equals(PREFIX_TEXT)) {
+ sb.append(getText(name));
+ } else { // PREFIX_RESOURCE
+ final String resourcePackageName = mResourcePackageName;
+ final RunInLocale<String> getTextJob = new RunInLocale<String>() {
+ @Override
+ protected String job(final Resources res) {
+ final int resId = res.getIdentifier(name, "string", resourcePackageName);
+ return res.getString(resId);
+ }
+ };
+ sb.append(getTextJob.runInLocale(mResources, mResourceLocale));
+ }
+ return end - 1;
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
index 3c33320ea..192011384 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsTable.java
@@ -209,48 +209,56 @@ public final class KeyboardTextsTable {
/* 123: 1 */ "morekeys_less_than",
/* 124: 1 */ "morekeys_greater_than",
/* 125: 1 */ "morekeys_exclamation",
- /* 126: 0 */ "morekeys_currency_generic",
- /* 127: 0 */ "morekeys_symbols_1",
- /* 128: 0 */ "morekeys_symbols_2",
- /* 129: 0 */ "morekeys_symbols_3",
- /* 130: 0 */ "morekeys_symbols_4",
- /* 131: 0 */ "morekeys_symbols_5",
- /* 132: 0 */ "morekeys_symbols_6",
- /* 133: 0 */ "morekeys_symbols_7",
- /* 134: 0 */ "morekeys_symbols_8",
- /* 135: 0 */ "morekeys_symbols_9",
- /* 136: 0 */ "morekeys_symbols_0",
- /* 137: 0 */ "morekeys_am_pm",
- /* 138: 0 */ "keyspec_settings",
- /* 139: 0 */ "keyspec_shortcut",
- /* 140: 0 */ "keyspec_action_next",
- /* 141: 0 */ "keyspec_action_previous",
- /* 142: 0 */ "keylabel_to_more_symbol",
- /* 143: 0 */ "keylabel_tablet_to_more_symbol",
- /* 144: 0 */ "keylabel_to_phone_numeric",
- /* 145: 0 */ "keylabel_to_phone_symbols",
- /* 146: 0 */ "keylabel_time_am",
- /* 147: 0 */ "keylabel_time_pm",
- /* 148: 0 */ "keyspec_popular_domain",
- /* 149: 0 */ "morekeys_popular_domain",
- /* 150: 0 */ "keyspecs_left_parenthesis_more_keys",
- /* 151: 0 */ "keyspecs_right_parenthesis_more_keys",
- /* 152: 0 */ "single_laqm_raqm",
- /* 153: 0 */ "single_raqm_laqm",
- /* 154: 0 */ "double_laqm_raqm",
- /* 155: 0 */ "double_raqm_laqm",
- /* 156: 0 */ "single_lqm_rqm",
- /* 157: 0 */ "single_9qm_lqm",
- /* 158: 0 */ "single_9qm_rqm",
- /* 159: 0 */ "single_rqm_9qm",
- /* 160: 0 */ "double_lqm_rqm",
- /* 161: 0 */ "double_9qm_lqm",
- /* 162: 0 */ "double_9qm_rqm",
- /* 163: 0 */ "double_rqm_9qm",
- /* 164: 0 */ "morekeys_single_quote",
- /* 165: 0 */ "morekeys_double_quote",
- /* 166: 0 */ "morekeys_tablet_double_quote",
- /* 167: 0 */ "keyspec_emoji_action_key",
+ /* 126: 1 */ "label_go_key",
+ /* 127: 1 */ "label_send_key",
+ /* 128: 1 */ "label_next_key",
+ /* 129: 1 */ "label_done_key",
+ /* 130: 1 */ "label_search_key",
+ /* 131: 1 */ "label_previous_key",
+ /* 132: 1 */ "label_pause_key",
+ /* 133: 1 */ "label_wait_key",
+ /* 134: 0 */ "morekeys_currency_generic",
+ /* 135: 0 */ "morekeys_symbols_1",
+ /* 136: 0 */ "morekeys_symbols_2",
+ /* 137: 0 */ "morekeys_symbols_3",
+ /* 138: 0 */ "morekeys_symbols_4",
+ /* 139: 0 */ "morekeys_symbols_5",
+ /* 140: 0 */ "morekeys_symbols_6",
+ /* 141: 0 */ "morekeys_symbols_7",
+ /* 142: 0 */ "morekeys_symbols_8",
+ /* 143: 0 */ "morekeys_symbols_9",
+ /* 144: 0 */ "morekeys_symbols_0",
+ /* 145: 0 */ "morekeys_am_pm",
+ /* 146: 0 */ "keyspec_settings",
+ /* 147: 0 */ "keyspec_shortcut",
+ /* 148: 0 */ "keyspec_action_next",
+ /* 149: 0 */ "keyspec_action_previous",
+ /* 150: 0 */ "keylabel_to_more_symbol",
+ /* 151: 0 */ "keylabel_tablet_to_more_symbol",
+ /* 152: 0 */ "keylabel_to_phone_numeric",
+ /* 153: 0 */ "keylabel_to_phone_symbols",
+ /* 154: 0 */ "keylabel_time_am",
+ /* 155: 0 */ "keylabel_time_pm",
+ /* 156: 0 */ "keyspec_popular_domain",
+ /* 157: 0 */ "morekeys_popular_domain",
+ /* 158: 0 */ "keyspecs_left_parenthesis_more_keys",
+ /* 159: 0 */ "keyspecs_right_parenthesis_more_keys",
+ /* 160: 0 */ "single_laqm_raqm",
+ /* 161: 0 */ "single_raqm_laqm",
+ /* 162: 0 */ "double_laqm_raqm",
+ /* 163: 0 */ "double_raqm_laqm",
+ /* 164: 0 */ "single_lqm_rqm",
+ /* 165: 0 */ "single_9qm_lqm",
+ /* 166: 0 */ "single_9qm_rqm",
+ /* 167: 0 */ "single_rqm_9qm",
+ /* 168: 0 */ "double_lqm_rqm",
+ /* 169: 0 */ "double_9qm_lqm",
+ /* 170: 0 */ "double_9qm_rqm",
+ /* 171: 0 */ "double_rqm_9qm",
+ /* 172: 0 */ "morekeys_single_quote",
+ /* 173: 0 */ "morekeys_double_quote",
+ /* 174: 0 */ "morekeys_tablet_double_quote",
+ /* 175: 0 */ "keyspec_emoji_action_key",
};
private static final String EMPTY = "";
@@ -379,6 +387,14 @@ public final class KeyboardTextsTable {
/* morekeys_greater_than */ "!fixedColumnOrder!3,!text/keyspec_right_single_angle_quote,!text/keyspec_greater_than_equal,!text/keyspec_right_double_angle_quote",
// U+00A1: "¡" INVERTED EXCLAMATION MARK
/* morekeys_exclamation */ "\u00A1",
+ /* label_go_key */ "!string/label_go_key",
+ /* label_send_key */ "!string/label_send_key",
+ /* label_next_key */ "!string/label_next_key",
+ /* label_done_key */ "!string/label_done_key",
+ /* label_search_key */ "!string/label_search_key",
+ /* label_previous_key */ "!string/label_previous_key",
+ /* label_pause_key */ "!string/label_pause_key",
+ /* label_wait_key */ "!string/label_wait_key",
/* morekeys_currency_generic */ "$,\u00A2,\u20AC,\u00A3,\u00A5,\u20B1",
// U+00B9: "¹" SUPERSCRIPT ONE
// U+00BD: "½" VULGAR FRACTION ONE HALF
@@ -1885,6 +1901,24 @@ public final class KeyboardTextsTable {
/* ~ morekeys_s */
// U+20B9: "₹" INDIAN RUPEE SIGN
/* keyspec_currency */ "\u20B9",
+ /* morekeys_y ~ */
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null, null, null, null, null, null, null,
+ null, null, null, null, null, null, null, null, null,
+ /* ~ morekeys_exclamation */
+ /* label_go_key */ "Go",
+ /* label_send_key */ "Send",
+ /* label_next_key */ "Next",
+ /* label_done_key */ "Done",
+ /* label_search_key */ "Search",
+ /* label_previous_key */ "Prev",
+ /* label_pause_key */ "Pause",
+ /* label_wait_key */ "Wait",
};
/* Locale hr: Croatian */
@@ -3952,7 +3986,7 @@ public final class KeyboardTextsTable {
private static final Object[] LOCALES_AND_TEXTS = {
// "locale", TEXT_ARRAY, /* numberOfNonNullText/lengthOf_TEXT_ARRAY localeName */
- "DEFAULT", TEXTS_DEFAULT, /* 168/168 DEFAULT */
+ "DEFAULT", TEXTS_DEFAULT, /* 176/176 DEFAULT */
"af" , TEXTS_af, /* 7/ 13 Afrikaans */
"ar" , TEXTS_ar, /* 55/110 Arabic */
"az_AZ" , TEXTS_az_AZ, /* 11/ 18 Azerbaijani (Azerbaijan) */
@@ -3974,7 +4008,7 @@ public final class KeyboardTextsTable {
"fr" , TEXTS_fr, /* 13/ 62 French */
"gl_ES" , TEXTS_gl_ES, /* 7/ 8 Gallegan (Spain) */
"hi" , TEXTS_hi, /* 23/ 53 Hindi */
- "hi_ZZ" , TEXTS_hi_ZZ, /* 1/ 12 Hindi (ZZ) */
+ "hi_ZZ" , TEXTS_hi_ZZ, /* 9/134 Hindi (ZZ) */
"hr" , TEXTS_hr, /* 9/ 20 Croatian */
"hu" , TEXTS_hu, /* 9/ 20 Hungarian */
"hy_AM" , TEXTS_hy_AM, /* 9/126 Armenian (Armenia) */
diff --git a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
index 96a6510fc..5a7f7662c 100644
--- a/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
+++ b/java/src/com/android/inputmethod/latin/utils/SubtypeLocaleUtils.java
@@ -167,7 +167,7 @@ public final class SubtypeLocaleUtils {
return nameId == null ? UNKNOWN_KEYBOARD_LAYOUT : nameId;
}
- private static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) {
+ public static Locale getDisplayLocaleOfSubtypeLocale(final String localeString) {
if (NO_LANGUAGE.equals(localeString)) {
return sResources.getConfiguration().locale;
}
diff --git a/tests/res/values/donottranslate.xml b/tests/res/values/donottranslate.xml
index 263d0af24..f26947608 100644
--- a/tests/res/values/donottranslate.xml
+++ b/tests/res/values/donottranslate.xml
@@ -50,13 +50,15 @@
<string name="multiple_labels_with_escape_surrounded_by_spaces">" \\abc , d\\ef , gh\\i "</string>
<string name="multiple_labels_with_comma_and_escape">"ab\\\\,d\\\\\\,,g\\,i"</string>
<string name="multiple_labels_with_comma_and_escape_surrounded_by_spaces">" ab\\\\ , d\\\\\\, , g\\,i "</string>
- <string name="indirect_string">!text/multiple_chars</string>
- <string name="indirect_string_with_literal">x,!text/multiple_chars,y</string>
- <string name="indirect2_string">!text/indirect_string</string>
- <string name="infinite_indirection">infinite,!text/infinite_indirection,loop</string>
- <string name="upper_indirect_string">!TEXT/MULTIPLE_CHARS</string>
- <string name="upper_indirect_string_with_literal">x,!TEXT/MULTIPLE_CHARS,y</string>
- <string name="upper_indirect2_string">!TEXT/UPPER_INDIRECT_STRING</string>
- <string name="upper_infinite_indirection">infinite,!TEXT/INFINITE_INDIRECTION,loop</string>
+ <string name="indirect_string">!string/multiple_chars</string>
+ <string name="indirect_string_with_literal">x,!string/multiple_chars,y</string>
+ <string name="indirect2_string">!string/indirect_string</string>
+ <string name="infinite_indirection">infinite,!string/infinite_indirection,loop</string>
+ <string name="upper_indirect_string">!STRING/MULTIPLE_CHARS</string>
+ <string name="upper_indirect_string_with_literal">x,!STRING/MULTIPLE_CHARS,y</string>
+ <string name="upper_indirect2_string">!STRING/UPPER_INDIRECT_STRING</string>
+ <string name="upper_infinite_indirection">infinite,!STRING/INFINITE_INDIRECTION,loop</string>
<string name="keyspec_indirect_navigate_actions">!fixedColumnOrder!2,!text/keyspec_action_previous,!text/keyspec_action_next</string>
+ <string name="label_next_key">ActionNext</string>
+ <string name="label_previous_key">ActionPrevious</string>
</resources>
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java
index 17cee29b3..22c22a00a 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelBase.java
@@ -25,6 +25,7 @@ import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyVisual;
import com.android.inputmethod.latin.Constants;
+import com.android.inputmethod.latin.utils.LocaleUtils;
import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
@@ -64,10 +65,11 @@ abstract class KeyboardLayoutSetActionLabelBase extends KeyboardLayoutSetTestsBa
}
protected static Locale getLabelLocale(final InputMethodSubtype subtype) {
- if (subtype.getLocale().equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
+ final String localeString = subtype.getLocale();
+ if (localeString.equals(SubtypeLocaleUtils.NO_LANGUAGE)) {
return null;
}
- return SubtypeLocaleUtils.getSubtypeLocale(subtype);
+ return LocaleUtils.constructLocaleFromString(localeString);
}
public void testActionUnspecified() {
diff --git a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java
index 07d47053a..36b9c9cfc 100644
--- a/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/KeyboardLayoutSetActionLabelKlpTests.java
@@ -22,15 +22,40 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.RichInputMethodManager;
import com.android.inputmethod.latin.utils.RunInLocale;
import com.android.inputmethod.latin.utils.SubtypeLocaleUtils;
+import java.util.ArrayList;
import java.util.Locale;
@MediumTest
public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActionLabelBase {
+ // Filter a subtype whose name should be displayed using {@link Locale#ROOT}, such like
+ // Hinglish (hi_ZZ) and Serbian-Latn (sr_ZZ).
+ static final SubtypeFilter SUBTYPE_FILTER_NAME_IN_BASE_LOCALE = new SubtypeFilter() {
+ @Override
+ public boolean accept(final InputMethodSubtype subtype) {
+ return Locale.ROOT.equals(
+ SubtypeLocaleUtils.getDisplayLocaleOfSubtypeLocale(subtype.getLocale()));
+ }
+ };
+
+ private ArrayList<InputMethodSubtype> mSubtypesWhoseNameIsDisplayedInItsLocale;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSubtypesWhoseNameIsDisplayedInItsLocale = getSubtypesFilteredBy(new SubtypeFilter() {
+ @Override
+ public boolean accept(final InputMethodSubtype subtype) {
+ return !SUBTYPE_FILTER_NAME_IN_BASE_LOCALE.accept(subtype);
+ }
+ });
+ }
+
@Override
protected int getKeyboardThemeForTests() {
return KeyboardTheme.THEME_ID_KLP;
@@ -38,7 +63,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
@Override
public void testActionGo() {
- for (final InputMethodSubtype subtype : getAllSubtypesList()) {
+ for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) {
final String tag = "go " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey(
R.string.label_go_key, getLabelLocale(subtype), getContext());
@@ -48,7 +73,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
@Override
public void testActionSend() {
- for (final InputMethodSubtype subtype : getAllSubtypesList()) {
+ for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) {
final String tag = "send " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey(
R.string.label_send_key, getLabelLocale(subtype), getContext());
@@ -58,7 +83,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
@Override
public void testActionNext() {
- for (final InputMethodSubtype subtype : getAllSubtypesList()) {
+ for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) {
final String tag = "next " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey(
R.string.label_next_key, getLabelLocale(subtype), getContext());
@@ -68,7 +93,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
@Override
public void testActionDone() {
- for (final InputMethodSubtype subtype : getAllSubtypesList()) {
+ for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) {
final String tag = "done " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey(
R.string.label_done_key, getLabelLocale(subtype), getContext());
@@ -78,7 +103,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
@Override
public void testActionPrevious() {
- for (final InputMethodSubtype subtype : getAllSubtypesList()) {
+ for (final InputMethodSubtype subtype : mSubtypesWhoseNameIsDisplayedInItsLocale) {
final String tag = "previous " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
final ExpectedActionKey expectedKey = ExpectedActionKey.newLabelKey(
R.string.label_previous_key, getLabelLocale(subtype), getContext());
@@ -105,7 +130,7 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
// Working variable to simulate system locale changing.
private Locale mSystemLocale = Locale.getDefault();
- private void doTestActionKeysInLocale(final InputMethodSubtype subtype,
+ private void doTestActionKeysInLocaleWithStringResources(final InputMethodSubtype subtype,
final Locale labelLocale, final Locale systemLocale) {
// Simulate system locale changing, see {@link SystemBroadcastReceiver}.
if (!systemLocale.equals(mSystemLocale)) {
@@ -144,10 +169,10 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
final InputMethodSubtype italian = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
Locale.ITALIAN.toString(), SubtypeLocaleUtils.QWERTY);
// An action label should be displayed in subtype's locale regardless of the system locale.
- doTestActionKeysInLocale(italian, Locale.ITALIAN, Locale.US);
- doTestActionKeysInLocale(italian, Locale.ITALIAN, Locale.FRENCH);
- doTestActionKeysInLocale(italian, Locale.ITALIAN, Locale.ITALIAN);
- doTestActionKeysInLocale(italian, Locale.ITALIAN, Locale.JAPANESE);
+ doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.US);
+ doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.FRENCH);
+ doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.ITALIAN);
+ doTestActionKeysInLocaleWithStringResources(italian, Locale.ITALIAN, Locale.JAPANESE);
}
public void testNoLanguageSubtypeActionLabel() {
@@ -155,9 +180,58 @@ public class KeyboardLayoutSetActionLabelKlpTests extends KeyboardLayoutSetActio
final InputMethodSubtype noLanguage = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
SubtypeLocaleUtils.NO_LANGUAGE, SubtypeLocaleUtils.QWERTY);
// An action label of no language keyboard should be displayed in the system locale.
- doTestActionKeysInLocale(noLanguage, Locale.US, Locale.US);
- doTestActionKeysInLocale(noLanguage, Locale.FRENCH, Locale.FRENCH);
- doTestActionKeysInLocale(noLanguage, Locale.ITALIAN, Locale.ITALIAN);
- doTestActionKeysInLocale(noLanguage, Locale.JAPANESE, Locale.JAPANESE);
+ doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.US, Locale.US);
+ doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.FRENCH, Locale.FRENCH);
+ doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.ITALIAN, Locale.ITALIAN);
+ doTestActionKeysInLocaleWithStringResources(noLanguage, Locale.JAPANESE, Locale.JAPANESE);
+ }
+
+ private void doTestActionKeysInLocaleWithKeyboardTextsSet(final InputMethodSubtype subtype,
+ final Locale labelLocale, final Locale systemLocale) {
+ // Simulate system locale changing, see {@link SystemBroadcastReceiver}.
+ if (!systemLocale.equals(mSystemLocale)) {
+ KeyboardLayoutSet.onSystemLocaleChanged();
+ mSystemLocale = systemLocale;
+ }
+ final KeyboardTextsSet textsSet = new KeyboardTextsSet();
+ textsSet.setLocale(labelLocale, getContext());
+ final ExpectedActionKey enterKey = ExpectedActionKey.newIconKey(
+ KeyboardIconsSet.NAME_ENTER_KEY);
+ final ExpectedActionKey goKey = ExpectedActionKey.newLabelKey(
+ textsSet.getText("label_go_key"));
+ final ExpectedActionKey searchKey = ExpectedActionKey.newIconKey(
+ KeyboardIconsSet.NAME_SEARCH_KEY);
+ final ExpectedActionKey sendKey = ExpectedActionKey.newLabelKey(
+ textsSet.getText("label_send_key"));
+ final ExpectedActionKey nextKey = ExpectedActionKey.newLabelKey(
+ textsSet.getText("label_next_key"));
+ final ExpectedActionKey doneKey = ExpectedActionKey.newLabelKey(
+ textsSet.getText("label_done_key"));
+ final ExpectedActionKey previousKey = ExpectedActionKey.newLabelKey(
+ textsSet.getText("label_previous_key"));
+ final String tag = "label=hi_ZZ system=" + systemLocale
+ + " " + SubtypeLocaleUtils.getSubtypeNameForLogging(subtype);
+ final RunInLocale<Void> job = new RunInLocale<Void>() {
+ @Override
+ public Void job(final Resources res) {
+ doTestActionKeys(subtype, tag, enterKey, enterKey, goKey, searchKey, sendKey,
+ nextKey, doneKey, previousKey);
+ return null;
+ }
+ };
+ job.runInLocale(getContext().getResources(), systemLocale);
+ }
+
+ public void testHinglishActionLabel() {
+ final RichInputMethodManager richImm = RichInputMethodManager.getInstance();
+ final Locale hi_ZZ = new Locale("hi", "ZZ");
+ final InputMethodSubtype hinglish = richImm.findSubtypeByLocaleAndKeyboardLayoutSet(
+ hi_ZZ.toString(), SubtypeLocaleUtils.QWERTY);
+ // An action label should be displayed in subtype's locale regardless of the system locale.
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, hi_ZZ);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.US);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.FRENCH);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.ITALIAN);
+ doTestActionKeysInLocaleWithKeyboardTextsSet(hinglish, hi_ZZ, Locale.JAPANESE);
}
}
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
index 922d2a8c8..8f4648c52 100644
--- a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecSplitTests.java
@@ -16,52 +16,33 @@
package com.android.inputmethod.keyboard.internal;
-import android.app.Instrumentation;
import android.content.Context;
import android.content.res.Resources;
-import android.test.InstrumentationTestCase;
-import android.test.suitebuilder.annotation.MediumTest;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.latin.R;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
-@MediumTest
-public class MoreKeySpecSplitTests extends InstrumentationTestCase {
+@SmallTest
+public class MoreKeySpecSplitTests extends AndroidTestCase {
private static final Locale TEST_LOCALE = Locale.ENGLISH;
- final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
+ private final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
@Override
protected void setUp() throws Exception {
super.setUp();
- final Instrumentation instrumentation = getInstrumentation();
- final Context targetContext = instrumentation.getTargetContext();
- mTextsSet.setLocale(TEST_LOCALE, targetContext);
- final String[] testResourceNames = getAllResourceIdNames(
- com.android.inputmethod.latin.tests.R.string.class);
- final Context testContext = instrumentation.getContext();
- final Resources testRes = testContext.getResources();
- final String testResPackageName = testRes.getResourcePackageName(
- // This dummy raw resource is needed to be able to load string resources from a test
- // APK successfully.
- com.android.inputmethod.latin.tests.R.raw.dummy_resource_for_testing);
- mTextsSet.loadStringResourcesInternal(testRes, testResourceNames, testResPackageName);
- }
-
- private static String[] getAllResourceIdNames(final Class<?> resourceIdClass) {
- final ArrayList<String> names = new ArrayList<>();
- for (final Field field : resourceIdClass.getFields()) {
- if (field.getType() == int.class) {
- names.add(field.getName());
- }
- }
- return names.toArray(new String[names.size()]);
+ final Context targetContext = getContext();
+ final Resources targetRes = targetContext.getResources();
+ final String targetPackageName = targetRes.getResourcePackageName(
+ R.string.english_ime_name);
+ mTextsSet.setLocale(TEST_LOCALE, targetRes, targetPackageName);
}
- private static <T> void assertArrayEquals(final String message, final T[] expected,
- final T[] actual) {
+ static <T> void assertArrayEquals(final String message, final T[] expected, final T[] actual) {
if (expected == actual) {
return;
}
@@ -109,14 +90,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase {
private static final String SURROGATE1 = PAIR1 + PAIR2;
private static final String SURROGATE2 = PAIR1 + PAIR2 + PAIR3;
- public void testResolveNullText() {
- assertNull("resolve null", mTextsSet.resolveTextReference(null));
- }
-
- public void testResolveEmptyText() {
- assertNull("resolve empty text", mTextsSet.resolveTextReference("!text/empty_string"));
- }
-
public void testSplitZero() {
assertTextArray("Empty string", "");
assertTextArray("Empty entry", ",");
@@ -224,132 +197,14 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase {
"\\!", "\\!TEXT/EMPTY_STRING");
}
- public void testSplitResourceError() {
- assertError("Incomplete resource name", "!text/", "!text/");
- assertError("Non existing resource", "!text/non_existing");
- }
-
- public void testSplitResourceZero() {
- assertTextArray("Empty string",
- "!text/empty_string");
- }
-
- public void testSplitResourceSingle() {
- assertTextArray("Single char",
- "!text/single_char", "a");
- assertTextArray("Space",
- "!text/space", " ");
- assertTextArray("Single label",
- "!text/single_label", "abc");
- assertTextArray("Spaces",
- "!text/spaces", " ");
- assertTextArray("Spaces in label",
- "!text/spaces_in_label", "a b c");
- assertTextArray("Spaces at beginning of label",
- "!text/spaces_at_beginning_of_label", " abc");
- assertTextArray("Spaces at end of label",
- "!text/spaces_at_end_of_label", "abc ");
- assertTextArray("label surrounded by spaces",
- "!text/label_surrounded_by_spaces", " abc ");
-
- assertTextArray("Escape and single char",
- "\\\\!text/single_char", "\\\\a");
- }
-
- public void testSplitResourceSingleEscaped() {
- assertTextArray("Escaped char",
- "!text/escaped_char", "\\a");
- assertTextArray("Escaped comma",
- "!text/escaped_comma", "\\,");
- assertTextArray("Escaped comma escape",
- "!text/escaped_comma_escape", "a\\,\\");
- assertTextArray("Escaped escape",
- "!text/escaped_escape", "\\\\");
- assertTextArray("Escaped label",
- "!text/escaped_label", "a\\bc");
- assertTextArray("Escaped label at beginning",
- "!text/escaped_label_at_beginning", "\\abc");
- assertTextArray("Escaped label at end",
- "!text/escaped_label_at_end", "abc\\");
- assertTextArray("Escaped label with comma",
- "!text/escaped_label_with_comma", "a\\,c");
- assertTextArray("Escaped label with comma at beginning",
- "!text/escaped_label_with_comma_at_beginning", "\\,bc");
- assertTextArray("Escaped label with comma at end",
- "!text/escaped_label_with_comma_at_end", "ab\\,");
- assertTextArray("Escaped label with successive",
- "!text/escaped_label_with_successive", "\\,\\\\bc");
- assertTextArray("Escaped label with escape",
- "!text/escaped_label_with_escape", "a\\\\c");
+ public void testSplitTextReferenceError() {
+ assertError("Incomplete text name", "!text/", "!text/");
+ assertError("Non existing text", "!text/non_existing");
}
- public void testSplitResourceMulti() {
- assertTextArray("Multiple chars",
- "!text/multiple_chars", "a", "b", "c");
- assertTextArray("Multiple chars surrounded by spaces",
- "!text/multiple_chars_surrounded_by_spaces",
- " a ", " b ", " c ");
- assertTextArray("Multiple labels",
- "!text/multiple_labels", "abc", "def", "ghi");
- assertTextArray("Multiple labels surrounded by spaces",
- "!text/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi ");
- }
-
- public void testSplitResourcetMultiEscaped() {
- assertTextArray("Multiple chars with comma",
- "!text/multiple_chars_with_comma",
- "a", "\\,", "c");
- assertTextArray("Multiple chars with comma surrounded by spaces",
- "!text/multiple_chars_with_comma_surrounded_by_spaces",
- " a ", " \\, ", " c ");
- assertTextArray("Multiple labels with escape",
- "!text/multiple_labels_with_escape",
- "\\abc", "d\\ef", "gh\\i");
- assertTextArray("Multiple labels with escape surrounded by spaces",
- "!text/multiple_labels_with_escape_surrounded_by_spaces",
- " \\abc ", " d\\ef ", " gh\\i ");
- assertTextArray("Multiple labels with comma and escape",
- "!text/multiple_labels_with_comma_and_escape",
- "ab\\\\", "d\\\\\\,", "g\\,i");
- assertTextArray("Multiple labels with comma and escape surrounded by spaces",
- "!text/multiple_labels_with_comma_and_escape_surrounded_by_spaces",
- " ab\\\\ ", " d\\\\\\, ", " g\\,i ");
- }
-
- public void testSplitMultipleResources() {
- assertTextArray("Literals and resources",
- "1,!text/multiple_chars,z", "1", "a", "b", "c", "z");
- assertTextArray("Literals and resources and escape at end",
- "\\1,!text/multiple_chars,z\\", "\\1", "a", "b", "c", "z\\");
- assertTextArray("Multiple single resource chars and labels",
- "!text/single_char,!text/single_label,!text/escaped_comma",
- "a", "abc", "\\,");
- assertTextArray("Multiple single resource chars and labels 2",
- "!text/single_char,!text/single_label,!text/escaped_comma_escape",
- "a", "abc", "a\\,\\");
- assertTextArray("Multiple multiple resource chars and labels",
- "!text/multiple_chars,!text/multiple_labels,!text/multiple_chars_with_comma",
- "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c");
- assertTextArray("Concatenated resources",
- "!text/multiple_chars!text/multiple_labels!text/multiple_chars_with_comma",
- "a", "b", "cabc", "def", "ghia", "\\,", "c");
- assertTextArray("Concatenated resource and literal",
- "abc!text/multiple_labels",
- "abcabc", "def", "ghi");
- }
-
- public void testSplitIndirectReference() {
- assertTextArray("Indirect",
- "!text/indirect_string", "a", "b", "c");
- assertTextArray("Indirect with literal",
- "1,!text/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2");
- assertTextArray("Indirect2",
- "!text/indirect2_string", "a", "b", "c");
- }
-
- public void testSplitInfiniteIndirectReference() {
- assertError("Infinite indirection",
- "1,!text/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2");
+ public void testSplitEmptyTextReference() {
+ // Note that morekeys_q of English locale is empty.
+ assertTextArray("Empty string", "!text/morekeys_q");
}
public void testLabelReferece() {
@@ -360,12 +215,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase {
assertTextArray("Settings as more key", "!text/keyspec_settings",
"!icon/settings_key|!code/key_settings");
-
- assertTextArray("Indirect naviagte actions as more key",
- "!text/keyspec_indirect_navigate_actions",
- "!fixedColumnOrder!2",
- "!hasLabels!", "Prev|!code/key_action_previous",
- "!hasLabels!", "Next|!code/key_action_next");
}
public void testUselessUpperCaseSpecifier() {
@@ -394,14 +243,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase {
assertTextArray("INDIRECT2",
"!TEXT/INDIRECT2_STRING", "!TEXT/INDIRECT2_STRING");
- assertTextArray("Upper indirect",
- "!text/upper_indirect_string", "!TEXT/MULTIPLE_CHARS");
- assertTextArray("Upper indirect with literal",
- "1,!text/upper_indirect_string_with_literal,2",
- "1", "x", "!TEXT/MULTIPLE_CHARS", "y", "2");
- assertTextArray("Upper indirect2",
- "!text/upper_indirect2_string", "!TEXT/UPPER_INDIRECT_STRING");
-
assertTextArray("UPPER INDIRECT",
"!TEXT/upper_INDIRECT_STRING", "!TEXT/upper_INDIRECT_STRING");
assertTextArray("Upper INDIRECT with literal",
@@ -413,9 +254,6 @@ public class MoreKeySpecSplitTests extends InstrumentationTestCase {
assertTextArray("INFINITE INDIRECTION",
"1,!TEXT/INFINITE_INDIRECTION,2", "1", "!TEXT/INFINITE_INDIRECTION", "2");
- assertTextArray("Upper infinite indirection",
- "1,!text/upper_infinite_indirection,2",
- "1", "infinite", "!TEXT/INFINITE_INDIRECTION", "loop", "2");
assertTextArray("Upper INFINITE INDIRECTION",
"1,!TEXT/UPPER_INFINITE_INDIRECTION,2",
"1", "!TEXT/UPPER_INFINITE_INDIRECTION", "2");
diff --git a/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java
new file mode 100644
index 000000000..e06ecaedf
--- /dev/null
+++ b/tests/src/com/android/inputmethod/keyboard/internal/MoreKeySpecStringReferenceTests.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.inputmethod.keyboard.internal;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.inputmethod.latin.tests.R;
+
+import java.util.Locale;
+
+@SmallTest
+public class MoreKeySpecStringReferenceTests extends InstrumentationTestCase {
+ private static final Locale TEST_LOCALE = Locale.ENGLISH;
+ private final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Instrumentation instrumentation = getInstrumentation();
+ final Context testContext = instrumentation.getContext();
+ final Resources testRes = testContext.getResources();
+ final String testPackageName = testRes.getResourcePackageName(R.string.empty_string);
+ mTextsSet.setLocale(TEST_LOCALE, testRes, testPackageName);
+ }
+
+ private void assertTextArray(final String message, final String value,
+ final String ... expectedArray) {
+ final String resolvedActual = mTextsSet.resolveTextReference(value);
+ final String[] actual = MoreKeySpec.splitKeySpecs(resolvedActual);
+ final String[] expected = (expectedArray.length == 0) ? null : expectedArray;
+ MoreKeySpecSplitTests.assertArrayEquals(message, expected, actual);
+ }
+
+ private void assertError(final String message, final String value, final String ... expected) {
+ try {
+ assertTextArray(message, value, expected);
+ fail(message);
+ } catch (Exception pcpe) {
+ // success.
+ }
+ }
+
+ public void testResolveNullText() {
+ assertEquals("resolve null",
+ mTextsSet.resolveTextReference(null), null);
+ }
+
+ public void testResolveEmptyText() {
+ assertEquals("resolve empty text",
+ mTextsSet.resolveTextReference("!string/empty_string"), null);
+ }
+
+ public void testSplitSingleEscaped() {
+ assertTextArray("Escaped !string", "\\!string",
+ "\\!string");
+ assertTextArray("Escaped !string/", "\\!string/",
+ "\\!string/");
+ assertTextArray("Escaped !STRING/", "\\!STRING/",
+ "\\!STRING/");
+ assertTextArray("Escaped !string/name", "\\!string/empty_string",
+ "\\!string/empty_string");
+ assertTextArray("Escaped !STRING/NAME", "\\!STRING/EMPTY_STRING",
+ "\\!STRING/EMPTY_STRING");
+ }
+
+ public void testSplitMultiEscaped() {
+ assertTextArray("Multiple escaped !string", "\\!,\\!string/empty_string",
+ "\\!", "\\!string/empty_string");
+ assertTextArray("Multiple escaped !STRING", "\\!,\\!STRING/EMPTY_STRING",
+ "\\!", "\\!STRING/EMPTY_STRING");
+ }
+
+ public void testSplitStringReferenceError() {
+ assertError("Incomplete resource name", "!string/", "!string/");
+ assertError("Non existing resource", "!string/non_existing");
+ }
+
+ public void testSplitEmptyStringReference() {
+ assertTextArray("Empty string", "!string/empty_string");
+ }
+
+ public void testSplitResourceSingle() {
+ assertTextArray("Single char", "!string/single_char",
+ "a");
+ assertTextArray("Space", "!string/space",
+ " ");
+ assertTextArray("Single label", "!string/single_label",
+ "abc");
+ assertTextArray("Spaces", "!string/spaces",
+ " ");
+ assertTextArray("Spaces in label", "!string/spaces_in_label",
+ "a b c");
+ assertTextArray("Spaces at beginning of label", "!string/spaces_at_beginning_of_label",
+ " abc");
+ assertTextArray("Spaces at end of label", "!string/spaces_at_end_of_label",
+ "abc ");
+ assertTextArray("label surrounded by spaces", "!string/label_surrounded_by_spaces",
+ " abc ");
+ assertTextArray("Escape and single char", "\\\\!string/single_char",
+ "\\\\a");
+ }
+
+ public void testSplitResourceSingleEscaped() {
+ assertTextArray("Escaped char",
+ "!string/escaped_char", "\\a");
+ assertTextArray("Escaped comma",
+ "!string/escaped_comma", "\\,");
+ assertTextArray("Escaped comma escape",
+ "!string/escaped_comma_escape", "a\\,\\");
+ assertTextArray("Escaped escape",
+ "!string/escaped_escape", "\\\\");
+ assertTextArray("Escaped label",
+ "!string/escaped_label", "a\\bc");
+ assertTextArray("Escaped label at beginning",
+ "!string/escaped_label_at_beginning", "\\abc");
+ assertTextArray("Escaped label at end",
+ "!string/escaped_label_at_end", "abc\\");
+ assertTextArray("Escaped label with comma",
+ "!string/escaped_label_with_comma", "a\\,c");
+ assertTextArray("Escaped label with comma at beginning",
+ "!string/escaped_label_with_comma_at_beginning", "\\,bc");
+ assertTextArray("Escaped label with comma at end",
+ "!string/escaped_label_with_comma_at_end", "ab\\,");
+ assertTextArray("Escaped label with successive",
+ "!string/escaped_label_with_successive", "\\,\\\\bc");
+ assertTextArray("Escaped label with escape",
+ "!string/escaped_label_with_escape", "a\\\\c");
+ }
+
+ public void testSplitResourceMulti() {
+ assertTextArray("Multiple chars",
+ "!string/multiple_chars", "a", "b", "c");
+ assertTextArray("Multiple chars surrounded by spaces",
+ "!string/multiple_chars_surrounded_by_spaces",
+ " a ", " b ", " c ");
+ assertTextArray("Multiple labels",
+ "!string/multiple_labels", "abc", "def", "ghi");
+ assertTextArray("Multiple labels surrounded by spaces",
+ "!string/multiple_labels_surrounded_by_spaces", " abc ", " def ", " ghi ");
+ }
+
+ public void testSplitResourcetMultiEscaped() {
+ assertTextArray("Multiple chars with comma",
+ "!string/multiple_chars_with_comma",
+ "a", "\\,", "c");
+ assertTextArray("Multiple chars with comma surrounded by spaces",
+ "!string/multiple_chars_with_comma_surrounded_by_spaces",
+ " a ", " \\, ", " c ");
+ assertTextArray("Multiple labels with escape",
+ "!string/multiple_labels_with_escape",
+ "\\abc", "d\\ef", "gh\\i");
+ assertTextArray("Multiple labels with escape surrounded by spaces",
+ "!string/multiple_labels_with_escape_surrounded_by_spaces",
+ " \\abc ", " d\\ef ", " gh\\i ");
+ assertTextArray("Multiple labels with comma and escape",
+ "!string/multiple_labels_with_comma_and_escape",
+ "ab\\\\", "d\\\\\\,", "g\\,i");
+ assertTextArray("Multiple labels with comma and escape surrounded by spaces",
+ "!string/multiple_labels_with_comma_and_escape_surrounded_by_spaces",
+ " ab\\\\ ", " d\\\\\\, ", " g\\,i ");
+ }
+
+ public void testSplitMultipleResources() {
+ assertTextArray("Literals and resources",
+ "1,!string/multiple_chars,z",
+ "1", "a", "b", "c", "z");
+ assertTextArray("Literals and resources and escape at end",
+ "\\1,!string/multiple_chars,z\\",
+ "\\1", "a", "b", "c", "z\\");
+ assertTextArray("Multiple single resource chars and labels",
+ "!string/single_char,!string/single_label,!string/escaped_comma",
+ "a", "abc", "\\,");
+ assertTextArray("Multiple single resource chars and labels 2",
+ "!string/single_char,!string/single_label,!string/escaped_comma_escape",
+ "a", "abc", "a\\,\\");
+ assertTextArray("Multiple multiple resource chars and labels",
+ "!string/multiple_chars,!string/multiple_labels,!string/multiple_chars_with_comma",
+ "a", "b", "c", "abc", "def", "ghi", "a", "\\,", "c");
+ assertTextArray("Concatenated resources",
+ "!string/multiple_chars!string/multiple_labels!string/multiple_chars_with_comma",
+ "a", "b", "cabc", "def", "ghia", "\\,", "c");
+ assertTextArray("Concatenated resource and literal",
+ "abc!string/multiple_labels",
+ "abcabc", "def", "ghi");
+ }
+
+ public void testSplitIndirectReference() {
+ assertTextArray("Indirect",
+ "!string/indirect_string", "a", "b", "c");
+ assertTextArray("Indirect with literal",
+ "1,!string/indirect_string_with_literal,2", "1", "x", "a", "b", "c", "y", "2");
+ assertTextArray("Indirect2",
+ "!string/indirect2_string", "a", "b", "c");
+ }
+
+ public void testSplitInfiniteIndirectReference() {
+ assertError("Infinite indirection",
+ "1,!string/infinite_indirection,2", "1", "infinite", "<infinite>", "loop", "2");
+ }
+
+ public void testLabelReferece() {
+ assertTextArray("Indirect naviagte actions as more key",
+ "!string/keyspec_indirect_navigate_actions",
+ "!fixedColumnOrder!2",
+ "!hasLabels!", "ActionPrevious|!code/key_action_previous",
+ "!hasLabels!", "ActionNext|!code/key_action_next");
+ }
+
+ public void testUselessUpperCaseSpecifier() {
+ assertTextArray("EMPTY STRING",
+ "!STRING/EMPTY_STRING", "!STRING/EMPTY_STRING");
+
+ assertTextArray("SINGLE CHAR",
+ "!STRING/SINGLE_CHAR", "!STRING/SINGLE_CHAR");
+ assertTextArray("Escape and SINGLE CHAR",
+ "\\\\!STRING/SINGLE_CHAR", "\\\\!STRING/SINGLE_CHAR");
+
+ assertTextArray("MULTIPLE CHARS",
+ "!STRING/MULTIPLE_CHARS", "!STRING/MULTIPLE_CHARS");
+
+ assertTextArray("Literals and RESOURCES",
+ "1,!STRING/MULTIPLE_CHARS,z", "1", "!STRING/MULTIPLE_CHARS", "z");
+ assertTextArray("Multiple single RESOURCE chars and LABELS 2",
+ "!STRING/SINGLE_CHAR,!STRING/SINGLE_LABEL,!STRING/ESCAPED_COMMA_ESCAPE",
+ "!STRING/SINGLE_CHAR", "!STRING/SINGLE_LABEL", "!STRING/ESCAPED_COMMA_ESCAPE");
+
+ assertTextArray("INDIRECT",
+ "!STRING/INDIRECT_STRING", "!STRING/INDIRECT_STRING");
+ assertTextArray("INDIRECT with literal",
+ "1,!STRING/INDIRECT_STRING_WITH_LITERAL,2",
+ "1", "!STRING/INDIRECT_STRING_WITH_LITERAL", "2");
+ assertTextArray("INDIRECT2",
+ "!STRING/INDIRECT2_STRING", "!STRING/INDIRECT2_STRING");
+
+ assertTextArray("Upper indirect",
+ "!string/upper_indirect_string", "!STRING/MULTIPLE_CHARS");
+ assertTextArray("Upper indirect with literal",
+ "1,!string/upper_indirect_string_with_literal,2",
+ "1", "x", "!STRING/MULTIPLE_CHARS", "y", "2");
+ assertTextArray("Upper indirect2",
+ "!string/upper_indirect2_string", "!STRING/UPPER_INDIRECT_STRING");
+
+ assertTextArray("UPPER INDIRECT",
+ "!STRING/upper_INDIRECT_STRING", "!STRING/upper_INDIRECT_STRING");
+ assertTextArray("Upper INDIRECT with literal",
+ "1,!STRING/upper_INDIRECT_STRING_WITH_LITERAL,2",
+ "1", "!STRING/upper_INDIRECT_STRING_WITH_LITERAL", "2");
+ assertTextArray("Upper INDIRECT2",
+ "!STRING/upper_INDIRECT2_STRING", "!STRING/upper_INDIRECT2_STRING");
+
+ assertTextArray("INFINITE INDIRECTION",
+ "1,!STRING/INFINITE_INDIRECTION,2", "1", "!STRING/INFINITE_INDIRECTION", "2");
+
+ assertTextArray("Upper infinite indirection",
+ "1,!string/upper_infinite_indirection,2",
+ "1", "infinite", "!STRING/INFINITE_INDIRECTION", "loop", "2");
+ assertTextArray("Upper INFINITE INDIRECTION",
+ "1,!STRING/UPPER_INFINITE_INDIRECTION,2",
+ "1", "!STRING/UPPER_INFINITE_INDIRECTION", "2");
+
+ assertTextArray("INDIRECT NAVIGATE ACTIONS AS MORE KEY",
+ "!STRING/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY",
+ "!STRING/INDIRECT_NAVIGATE_ACTIONS_AS_MORE_KEY");
+ }
+}
diff --git a/tools/make-keyboard-text/res/values-hi-rZZ/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values-hi-rZZ/donottranslate-more-keys.xml
index 068639d77..50834e0fc 100644
--- a/tools/make-keyboard-text/res/values-hi-rZZ/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values-hi-rZZ/donottranslate-more-keys.xml
@@ -20,4 +20,12 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- U+20B9: "₹" INDIAN RUPEE SIGN -->
<string name="keyspec_currency">&#x20B9;</string>
+ <string name="label_go_key">Go</string>
+ <string name="label_send_key">Send</string>
+ <string name="label_next_key">Next</string>
+ <string name="label_done_key">Done</string>
+ <string name="label_search_key">Search</string>
+ <string name="label_previous_key">Prev</string>
+ <string name="label_pause_key">Pause</string>
+ <string name="label_wait_key">Wait</string>
</resources>
diff --git a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
index c4a1b889e..b6da7d13d 100644
--- a/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
+++ b/tools/make-keyboard-text/res/values/donottranslate-more-keys.xml
@@ -259,4 +259,12 @@
<string name="morekeys_double_quote">!fixedColumnOrder!5,!text/double_quotes,!text/double_angle_quotes</string>
<string name="morekeys_tablet_double_quote">!fixedColumnOrder!6,!text/double_quotes,!text/single_quotes,!text/double_angle_quotes,!text/single_angle_quotes</string>
<string name="keyspec_emoji_action_key">!icon/emoji_action_key|!code/key_emoji</string>
+ <string name="label_go_key">!string/label_go_key</string>
+ <string name="label_send_key">!string/label_send_key</string>
+ <string name="label_next_key">!string/label_next_key</string>
+ <string name="label_done_key">!string/label_done_key</string>
+ <string name="label_search_key">!string/label_search_key</string>
+ <string name="label_previous_key">!string/label_previous_key</string>
+ <string name="label_pause_key">!string/label_pause_key</string>
+ <string name="label_wait_key">!string/label_wait_key</string>
</resources>