Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 853e8d88 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Add KeySpecParser unit test

Change-Id: Ie1c32daecefc2909e58056f515631cbd7de687f7
parent 1d3058da
Loading
Loading
Loading
Loading
+332 −0
Original line number Diff line number Diff line
/*
 * 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 static com.android.inputmethod.keyboard.internal.KeyboardCodesSet.PREFIX_CODE;
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.PREFIX_ICON;
import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;

import android.content.Context;
import android.content.res.Resources;
import android.test.AndroidTestCase;

import com.android.inputmethod.latin.utils.RunInLocale;

import java.util.Locale;

abstract class KeySpecParserBase extends AndroidTestCase {
    private final static Locale TEST_LOCALE = Locale.ENGLISH;
    protected final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
    protected final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();

    private static final String CODE_SETTINGS_NAME = "key_settings";
    private static final String CODE_SETTINGS = PREFIX_CODE + CODE_SETTINGS_NAME;
    private static final String ICON_SETTINGS_NAME = "settings_key";
    private static final String ICON_SETTINGS = PREFIX_ICON + ICON_SETTINGS_NAME;
    private static final String CODE_SETTINGS_UPPERCASE = CODE_SETTINGS.toUpperCase(Locale.ROOT);
    private static final String ICON_SETTINGS_UPPERCASE = ICON_SETTINGS.toUpperCase(Locale.ROOT);
    private static final String CODE_NON_EXISTING = PREFIX_CODE + "non_existing";
    private static final String ICON_NON_EXISTING = PREFIX_ICON + "non_existing";

    private int mCodeSettings;
    private int mCodeActionNext;
    private int mSettingsIconId;

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        final String language = TEST_LOCALE.getLanguage();
        mCodesSet.setLanguage(language);
        mTextsSet.setLanguage(language);
        final Context context = getContext();
        new RunInLocale<Void>() {
            @Override
            protected Void job(final Resources res) {
                mTextsSet.loadStringResources(context);
                return null;
            }
        }.runInLocale(context.getResources(), TEST_LOCALE);

        mCodeSettings = mCodesSet.getCode(CODE_SETTINGS_NAME);
        mCodeActionNext = mCodesSet.getCode("key_action_next");
        mSettingsIconId = KeyboardIconsSet.getIconId(ICON_SETTINGS_NAME);
    }

    abstract protected void assertParser(final String message, final String keySpec,
            final String expectedLabel, final String expectedOutputText, final int expectedIcon,
            final int expectedCode);

    protected void assertParserError(final String message, final String keySpec,
            final String expectedLabel, final String expectedOutputText, final int expectedIconId,
            final int expectedCode) {
        try {
            assertParser(message, keySpec, expectedLabel, expectedOutputText, expectedIconId,
                    expectedCode);
            fail(message);
        } catch (Exception pcpe) {
            // success.
        }
    }

    // \U001d11e: MUSICAL SYMBOL G CLEF
    private static final String SURROGATE_PAIR1 = "\ud834\udd1e";
    private static final int SURROGATE_CODE1 = SURROGATE_PAIR1.codePointAt(0);
    // \U001d122: MUSICAL SYMBOL F CLEF
    private static final String SURROGATE_PAIR2 = "\ud834\udd22";
    private static final int SURROGATE_CODE2 = SURROGATE_PAIR2.codePointAt(0);
    // \U002f8a6: CJK COMPATIBILITY IDEOGRAPH-2F8A6; variant character of \u6148.
    private static final String SURROGATE_PAIR3 = "\ud87e\udca6";
    private static final String SURROGATE_PAIRS4 = SURROGATE_PAIR1 + SURROGATE_PAIR2;
    private static final String SURROGATE_PAIRS5 = SURROGATE_PAIRS4 + SURROGATE_PAIR3;

    public void testSingleLetter() {
        assertParser("Single letter", "a",
                "a", null, ICON_UNDEFINED, 'a');
        assertParser("Single surrogate", SURROGATE_PAIR1,
                SURROGATE_PAIR1, null, ICON_UNDEFINED, SURROGATE_CODE1);
        assertParser("Single escaped bar", "\\|",
                "|", null, ICON_UNDEFINED, '|');
        assertParser("Single escaped escape", "\\\\",
                "\\", null, ICON_UNDEFINED, '\\');
        assertParser("Single comma", ",",
                ",", null, ICON_UNDEFINED, ',');
        assertParser("Single escaped comma", "\\,",
                ",", null, ICON_UNDEFINED, ',');
        assertParser("Single escaped letter", "\\a",
                "a", null, ICON_UNDEFINED, 'a');
        assertParser("Single escaped surrogate", "\\" + SURROGATE_PAIR2,
                SURROGATE_PAIR2, null, ICON_UNDEFINED, SURROGATE_CODE2);
        assertParser("Single bang", "!",
                "!", null, ICON_UNDEFINED, '!');
        assertParser("Single escaped bang", "\\!",
                "!", null, ICON_UNDEFINED, '!');
        assertParser("Single output text letter", "a|a",
                "a", null, ICON_UNDEFINED, 'a');
        assertParser("Single surrogate pair outputText", "G Clef|" + SURROGATE_PAIR1,
                "G Clef", null, ICON_UNDEFINED, SURROGATE_CODE1);
        assertParser("Single letter with outputText", "a|abc",
                "a", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with surrogate outputText", "a|" + SURROGATE_PAIRS4,
                "a", SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single surrogate with outputText", SURROGATE_PAIR3 + "|abc",
                SURROGATE_PAIR3, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with escaped outputText", "a|a\\|c",
                "a", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with escaped surrogate outputText",
                "a|" + SURROGATE_PAIR1 + "\\|" + SURROGATE_PAIR2,
                "a", SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with comma outputText", "a|a,b",
                "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with escaped comma outputText", "a|a\\,b",
                "a", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with outputText starts with bang", "a|!bc",
                "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with surrogate outputText starts with bang",
                "a|!" + SURROGATE_PAIRS5,
                "a", "!" + SURROGATE_PAIRS5, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with outputText contains bang", "a|a!c",
                "a", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single letter with escaped bang outputText", "a|\\!bc",
                "a", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Single escaped escape with single outputText", "\\\\|\\\\",
                "\\", null, ICON_UNDEFINED, '\\');
        assertParser("Single escaped bar with single outputText", "\\||\\|",
                "|", null, ICON_UNDEFINED, '|');
        assertParser("Single letter with code", "a|" + CODE_SETTINGS,
                "a", null, ICON_UNDEFINED, mCodeSettings);
    }

    public void testLabel() {
        assertParser("Simple label", "abc",
                "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Simple surrogate label", SURROGATE_PAIRS4,
                SURROGATE_PAIRS4, SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped bar", "a\\|c",
                "a|c", "a|c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Surrogate label with escaped bar", SURROGATE_PAIR1 + "\\|" + SURROGATE_PAIR2,
                SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2, SURROGATE_PAIR1 + "|" + SURROGATE_PAIR2,
                ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped escape", "a\\\\c",
                "a\\c", "a\\c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with comma", "a,c",
                "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped comma", "a\\,c",
                "a,c", "a,c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label starts with bang", "!bc",
                "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Surrogate label starts with bang", "!" + SURROGATE_PAIRS4,
                "!" + SURROGATE_PAIRS4, "!" + SURROGATE_PAIRS4, ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label contains bang", "a!c",
                "a!c", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped bang", "\\!bc",
                "!bc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped letter", "\\abc",
                "abc", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with outputText", "abc|def",
                "abc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with comma and outputText", "a,c|def",
                "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped comma label with outputText", "a\\,c|def",
                "a,c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped label with outputText", "a\\|c|def",
                "a|c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped bar outputText", "abc|d\\|f",
                "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped escape label with outputText", "a\\\\|def",
                "a\\", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label starts with bang and outputText", "!bc|def",
                "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label contains bang label and outputText", "a!c|def",
                "a!c", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped bang label with outputText", "\\!bc|def",
                "!bc", "def", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with comma outputText", "abc|a,b",
                "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped comma outputText", "abc|a\\,b",
                "abc", "a,b", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with outputText starts with bang", "abc|!bc",
                "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with outputText contains bang", "abc|a!c",
                "abc", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped bang outputText", "abc|\\!bc",
                "abc", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with escaped bar outputText", "abc|d\\|f",
                "abc", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped bar label with escaped bar outputText", "a\\|c|d\\|f",
                "a|c", "d|f", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with code", "abc|" + CODE_SETTINGS,
                "abc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped label with code", "a\\|c|" + CODE_SETTINGS,
                "a|c", null, ICON_UNDEFINED, mCodeSettings);
    }

    public void testIcons() {
        assertParser("Icon with single letter", ICON_SETTINGS + "|a",
                null, null, mSettingsIconId, 'a');
        assertParser("Icon with outputText", ICON_SETTINGS + "|abc",
                null, "abc", mSettingsIconId, CODE_OUTPUT_TEXT);
        assertParser("Icon with outputText starts with bang", ICON_SETTINGS + "|!bc",
                null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
        assertParser("Icon with outputText contains bang", ICON_SETTINGS + "|a!c",
                null, "a!c", mSettingsIconId, CODE_OUTPUT_TEXT);
        assertParser("Icon with escaped bang outputText", ICON_SETTINGS + "|\\!bc",
                null, "!bc", mSettingsIconId, CODE_OUTPUT_TEXT);
        assertParser("Label starts with bang and code", "!bc|" + CODE_SETTINGS,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Label contains bang and code", "a!c|" + CODE_SETTINGS,
                "a!c", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Escaped bang label with code", "\\!bc|" + CODE_SETTINGS,
                "!bc", null, ICON_UNDEFINED, mCodeSettings);
        assertParser("Icon with code", ICON_SETTINGS + "|" + CODE_SETTINGS,
                null, null, mSettingsIconId, mCodeSettings);
    }

    public void testResourceReference() {
        assertParser("Settings as more key", "!text/settings_as_more_key",
                null, null, mSettingsIconId, mCodeSettings);

        assertParser("Action next as more key", "!text/label_next_key|!code/key_action_next",
                "Next", null, ICON_UNDEFINED, mCodeActionNext);

        assertParser("Popular domain",
                "!text/keylabel_for_popular_domain|!text/keylabel_for_popular_domain ",
                ".com", ".com ", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
    }

    public void testFormatError() {
        assertParserError("Empty spec", "", null,
                null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Empty label with outputText", "|a",
                null, "a", ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Empty label with code", "|" + CODE_SETTINGS,
                null, null, ICON_UNDEFINED, mCodeSettings);
        assertParserError("Empty outputText with label", "a|",
                "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Empty outputText with icon", ICON_SETTINGS + "|",
                null, null, mSettingsIconId, CODE_UNSPECIFIED);
        assertParserError("Empty icon and code", "|",
                null, null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Icon without code", ICON_SETTINGS,
                null, null, mSettingsIconId, CODE_UNSPECIFIED);
        assertParserError("Non existing icon", ICON_NON_EXISTING + "|abc",
                null, "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParserError("Non existing code", "abc|" + CODE_NON_EXISTING,
                "abc", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Third bar at end", "a|b|",
                "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Multiple bar", "a|b|c",
                "a", null, ICON_UNDEFINED, CODE_UNSPECIFIED);
        assertParserError("Multiple bar with label and code", "a|" + CODE_SETTINGS + "|c",
                "a", null, ICON_UNDEFINED, mCodeSettings);
        assertParserError("Multiple bar with icon and outputText", ICON_SETTINGS + "|b|c",
                null, null, mSettingsIconId, CODE_UNSPECIFIED);
        assertParserError("Multiple bar with icon and code",
                ICON_SETTINGS + "|" + CODE_SETTINGS + "|c",
                null, null, mSettingsIconId, mCodeSettings);
    }

    public void testUselessUpperCaseSpecifier() {
        assertParser("Single letter with CODE", "a|" + CODE_SETTINGS_UPPERCASE,
                "a", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label with CODE", "abc|" + CODE_SETTINGS_UPPERCASE,
                "abc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped label with CODE", "a\\|c|" + CODE_SETTINGS_UPPERCASE,
                "a|c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("ICON with outputText", ICON_SETTINGS_UPPERCASE + "|abc",
                "!ICON/SETTINGS_KEY", "abc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("ICON with outputText starts with bang", ICON_SETTINGS_UPPERCASE + "|!bc",
                "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("ICON with outputText contains bang", ICON_SETTINGS_UPPERCASE + "|a!c",
                "!ICON/SETTINGS_KEY", "a!c", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("ICON with escaped bang outputText", ICON_SETTINGS_UPPERCASE + "|\\!bc",
                "!ICON/SETTINGS_KEY", "!bc", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label starts with bang and CODE", "!bc|" + CODE_SETTINGS_UPPERCASE,
                "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Label contains bang and CODE", "a!c|" + CODE_SETTINGS_UPPERCASE,
                "a!c", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("Escaped bang label with CODE", "\\!bc|" + CODE_SETTINGS_UPPERCASE,
                "!bc", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("ICON with CODE", ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE,
                "!ICON/SETTINGS_KEY", "!CODE/KEY_SETTINGS", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParser("SETTINGS AS MORE KEY", "!TEXT/SETTINGS_AS_MORE_KEY",
                "!TEXT/SETTINGS_AS_MORE_KEY", "!TEXT/SETTINGS_AS_MORE_KEY", ICON_UNDEFINED,
                CODE_OUTPUT_TEXT);
        assertParser("ACTION NEXT AS MORE KEY", "!TEXT/LABEL_NEXT_KEY|!CODE/KEY_ACTION_NEXT",
                "!TEXT/LABEL_NEXT_KEY", "!CODE/KEY_ACTION_NEXT", ICON_UNDEFINED,
                CODE_OUTPUT_TEXT);
        assertParser("POPULAR DOMAIN",
                "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN|!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
                "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN", "!TEXT/KEYLABEL_FOR_POPULAR_DOMAIN ",
                ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParserError("Empty label with CODE", "|" + CODE_SETTINGS_UPPERCASE,
                null, null, ICON_UNDEFINED, mCodeSettings);
        assertParserError("Empty outputText with ICON", ICON_SETTINGS_UPPERCASE + "|",
                null, null, mSettingsIconId, CODE_UNSPECIFIED);
        assertParser("ICON without code", ICON_SETTINGS_UPPERCASE,
                "!ICON/SETTINGS_KEY", "!ICON/SETTINGS_KEY", ICON_UNDEFINED, CODE_OUTPUT_TEXT);
        assertParserError("Multiple bar with label and CODE", "a|" + CODE_SETTINGS_UPPERCASE + "|c",
                "a", null, ICON_UNDEFINED, mCodeSettings);
        assertParserError("Multiple bar with ICON and outputText", ICON_SETTINGS_UPPERCASE + "|b|c",
                null, null, mSettingsIconId, CODE_UNSPECIFIED);
        assertParserError("Multiple bar with ICON and CODE",
                ICON_SETTINGS_UPPERCASE + "|" + CODE_SETTINGS_UPPERCASE + "|c",
                null, null, mSettingsIconId, mCodeSettings);
    }
}
+43 −0
Original line number Diff line number Diff line
/*
 * 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.test.suitebuilder.annotation.SmallTest;

import com.android.inputmethod.latin.Constants;

@SmallTest
public final class KeySpecParserTests extends KeySpecParserBase {
    @Override
    protected void assertParser(final String message, final String keySpec,
            final String expectedLabel, final String expectedOutputText, final int expectedIcon,
            final int expectedCode) {
        final String keySpecResolved = mTextsSet.resolveTextReference(keySpec);
        final String actualLabel = KeySpecParser.getLabel(keySpecResolved);
        final String actualOutputText = KeySpecParser.getOutputText(keySpecResolved);
        final int actualIcon = KeySpecParser.getIconId(keySpecResolved);
        final int actualCode = KeySpecParser.getCode(keySpecResolved, mCodesSet);
        assertEquals(message + " [label]", expectedLabel, actualLabel);
        assertEquals(message + " [ouptputText]", expectedOutputText, actualOutputText);
        assertEquals(message + " [icon]",
                KeyboardIconsSet.getIconName(expectedIcon),
                KeyboardIconsSet.getIconName(actualIcon));
        assertEquals(message + " [code]",
                Constants.printableCode(expectedCode),
                Constants.printableCode(actualCode));
    }
}
+4 −303

File changed.

Preview size limit exceeded, changes collapsed.