blob: 19d5fcdb7ab3961035a268f5c42a15f87756d8fe [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Keymap utils of Mozc interface.
#include <sstream>
#include <vector>
#include "base/config_file_stream.h"
#include "base/scoped_ptr.h"
#include "base/system_util.h"
#include "config/config.pb.h"
#include "config/config_handler.h"
#include "session/commands.pb.h"
#include "session/internal/keymap.h"
#include "session/internal/keymap-inl.h"
#include "session/internal/keymap_factory.h"
#include "session/key_parser.h"
#include "testing/base/public/gunit.h"
DECLARE_string(test_tmpdir);
namespace mozc {
namespace keymap {
class KeyMapTest : public testing::Test {
protected:
virtual void SetUp() {
SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);
config::Config config;
config::ConfigHandler::GetDefaultConfig(&config);
config::ConfigHandler::SetConfig(config);
}
virtual void TearDown() {
// just in case, reset the config in test_tmpdir
config::Config config;
config::ConfigHandler::GetDefaultConfig(&config);
config::ConfigHandler::SetConfig(config);
}
bool isInputModeXCommandSupported() const {
return KeyMapManager::kInputModeXCommandSupported;
}
};
TEST_F(KeyMapTest, AddRule) {
KeyMap<PrecompositionState> keymap;
commands::KeyEvent key_event;
// 'a'
key_event.set_key_code(97);
EXPECT_TRUE(keymap.AddRule(key_event, PrecompositionState::INSERT_CHARACTER));
// 0 is treated as null input
key_event.set_key_code(0);
EXPECT_TRUE(keymap.AddRule(key_event, PrecompositionState::INSERT_CHARACTER));
// 1 to 31 should be rejected.
key_event.set_key_code(1);
EXPECT_FALSE(keymap.AddRule(key_event,
PrecompositionState::INSERT_CHARACTER));
key_event.set_key_code(31);
EXPECT_FALSE(keymap.AddRule(key_event,
PrecompositionState::INSERT_CHARACTER));
// 32 (space) is also invalid input.
key_event.set_key_code(32);
EXPECT_FALSE(keymap.AddRule(key_event,
PrecompositionState::INSERT_CHARACTER));
// 33 (!) is a valid input.
key_event.set_key_code(33);
EXPECT_TRUE(keymap.AddRule(key_event, PrecompositionState::INSERT_CHARACTER));
// 8bit char is a valid input.
key_event.set_key_code(127);
EXPECT_TRUE(keymap.AddRule(key_event, PrecompositionState::INSERT_CHARACTER));
key_event.set_key_code(255);
EXPECT_TRUE(keymap.AddRule(key_event, PrecompositionState::INSERT_CHARACTER));
}
TEST_F(KeyMapTest, GetCommand) {
{
KeyMap<PrecompositionState> keymap;
commands::KeyEvent init_key_event;
init_key_event.set_key_code(97);
EXPECT_TRUE(keymap.AddRule(init_key_event,
PrecompositionState::INSERT_CHARACTER));
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_code(97);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
key_event.Clear();
key_event.set_key_code(98);
EXPECT_FALSE(keymap.GetCommand(key_event, &command));
}
{
KeyMap<PrecompositionState> keymap;
commands::KeyEvent init_key_event;
init_key_event.set_special_key(commands::KeyEvent::TEXT_INPUT);
EXPECT_TRUE(keymap.AddRule(init_key_event,
PrecompositionState::INSERT_CHARACTER));
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_string("hoge");
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
}
{
KeyMap<CompositionState> keymap;
commands::KeyEvent init_key_event;
init_key_event.set_key_code(97);
EXPECT_TRUE(keymap.AddRule(init_key_event,
CompositionState::INSERT_CHARACTER));
commands::KeyEvent key_event;
CompositionState::Commands command;
key_event.set_key_code(97);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(CompositionState::INSERT_CHARACTER, command);
key_event.Clear();
key_event.set_key_code(98);
EXPECT_FALSE(keymap.GetCommand(key_event, &command));
}
{
KeyMap<CompositionState> keymap;
commands::KeyEvent init_key_event;
init_key_event.set_special_key(commands::KeyEvent::ENTER);
EXPECT_TRUE(keymap.AddRule(init_key_event, CompositionState::COMMIT));
init_key_event.Clear();
init_key_event.set_special_key(commands::KeyEvent::DEL);
init_key_event.add_modifier_keys(commands::KeyEvent::CTRL);
init_key_event.add_modifier_keys(commands::KeyEvent::ALT);
EXPECT_TRUE(keymap.AddRule(init_key_event, CompositionState::IME_OFF));
commands::KeyEvent key_event;
CompositionState::Commands command;
// ENTER
key_event.Clear();
key_event.set_special_key(commands::KeyEvent::ENTER);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(CompositionState::COMMIT, command);
// CTRL-ALT-DELETE
key_event.Clear();
key_event.set_special_key(commands::KeyEvent::DEL);
key_event.add_modifier_keys(commands::KeyEvent::CTRL);
key_event.add_modifier_keys(commands::KeyEvent::ALT);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(CompositionState::IME_OFF, command);
}
}
TEST_F(KeyMapTest, GetCommandForKeyString) {
KeyMap<PrecompositionState> keymap;
// When a key event is not registered, GetCommand should return false.
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_code(97);
EXPECT_FALSE(keymap.GetCommand(key_event, &command));
}
// When a key event is not registered, GetCommand should return false even if
// the key event has |key_string|. See also b/9684668
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_code(97);
key_event.set_key_string("a");
EXPECT_FALSE(keymap.GetCommand(key_event, &command));
}
// Special case for b/4170089. VK_PACKET on Windows will be encoded as
// {
// key_code: (empty)
// key_string: (the Unicode string to be input)
// }
// We always treat such key events as INSERT_CHARACTER command.
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_string("a");
EXPECT_FALSE(keymap.GetCommand(key_event, &command));
}
// After adding the rule of TEXT_INPUT -> INSERT_CHARACTER, the above cases
// should return INSERT_CHARACTER.
commands::KeyEvent text_input_key_event;
text_input_key_event.set_special_key(commands::KeyEvent::TEXT_INPUT);
keymap.AddRule(text_input_key_event, PrecompositionState::INSERT_CHARACTER);
// key_code = 97, key_string = empty
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_code(97);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
}
// key_code = 97, key_string = "a"
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_code(97);
key_event.set_key_string("a");
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
}
// key_code = empty, key_string = "a"
{
commands::KeyEvent key_event;
PrecompositionState::Commands command;
key_event.set_key_string("a");
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
}
}
TEST_F(KeyMapTest, GetCommandKeyStub) {
KeyMap<PrecompositionState> keymap;
commands::KeyEvent init_key_event;
init_key_event.set_special_key(commands::KeyEvent::TEXT_INPUT);
EXPECT_TRUE(keymap.AddRule(init_key_event,
PrecompositionState::INSERT_CHARACTER));
PrecompositionState::Commands command;
commands::KeyEvent key_event;
key_event.set_key_code(97);
EXPECT_TRUE(keymap.GetCommand(key_event, &command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, command);
}
TEST_F(KeyMapTest, GetKeyMapFileName) {
EXPECT_STREQ("system://atok.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::ATOK));
EXPECT_STREQ("system://mobile.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::MOBILE));
EXPECT_STREQ("system://ms-ime.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::MSIME));
EXPECT_STREQ("system://kotoeri.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::KOTOERI));
EXPECT_STREQ("system://chromeos.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::CHROMEOS));
EXPECT_STREQ("user://keymap.tsv",
KeyMapManager::GetKeyMapFileName(config::Config::CUSTOM));
}
TEST_F(KeyMapTest, DefaultKeyBindings) {
KeyMapManager manager;
istringstream iss("", istringstream::in);
EXPECT_TRUE(manager.LoadStream(&iss));
{ // Check key bindings of TextInput.
commands::KeyEvent key_event;
KeyParser::ParseKey("TextInput", &key_event);
PrecompositionState::Commands fund_command;
EXPECT_TRUE(manager.GetCommandPrecomposition(key_event, &fund_command));
EXPECT_EQ(PrecompositionState::INSERT_CHARACTER, fund_command);
CompositionState::Commands composition_command;
EXPECT_TRUE(manager.GetCommandComposition(key_event, &composition_command));
EXPECT_EQ(CompositionState::INSERT_CHARACTER, composition_command);
ConversionState::Commands conv_command;
EXPECT_TRUE(manager.GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::INSERT_CHARACTER, conv_command);
}
{ // Check key bindings of Shift.
commands::KeyEvent key_event;
KeyParser::ParseKey("Shift", &key_event);
PrecompositionState::Commands fund_command;
EXPECT_FALSE(manager.GetCommandPrecomposition(key_event, &fund_command));
CompositionState::Commands composition_command;
EXPECT_TRUE(manager.GetCommandComposition(key_event, &composition_command));
EXPECT_EQ(CompositionState::INSERT_CHARACTER, composition_command);
ConversionState::Commands conv_command;
EXPECT_FALSE(manager.GetCommandConversion(key_event, &conv_command));
}
}
TEST_F(KeyMapTest, LoadStreamWithErrors) {
KeyMapManager manager;
vector<string> errors;
scoped_ptr<istream> is(ConfigFileStream::LegacyOpen("system://atok.tsv"));
EXPECT_TRUE(manager.LoadStreamWithErrors(is.get(), &errors));
EXPECT_TRUE(errors.empty());
errors.clear();
is.reset(ConfigFileStream::LegacyOpen("system://ms-ime.tsv"));
EXPECT_TRUE(manager.LoadStreamWithErrors(is.get(), &errors));
EXPECT_TRUE(errors.empty());
errors.clear();
is.reset(ConfigFileStream::LegacyOpen("system://kotoeri.tsv"));
EXPECT_TRUE(manager.LoadStreamWithErrors(is.get(), &errors));
EXPECT_TRUE(errors.empty());
errors.clear();
is.reset(ConfigFileStream::LegacyOpen("system://mobile.tsv"));
EXPECT_TRUE(manager.LoadStreamWithErrors(is.get(), &errors));
EXPECT_TRUE(errors.empty());
}
TEST_F(KeyMapTest, GetName) {
KeyMapManager manager;
{
// Direct
string name;
EXPECT_TRUE(manager.GetNameFromCommandDirect(DirectInputState::IME_ON,
&name));
EXPECT_EQ("IMEOn", name);
EXPECT_TRUE(manager.GetNameFromCommandDirect(DirectInputState::RECONVERT,
&name));
EXPECT_EQ("Reconvert", name);
}
{
// Precomposition
string name;
EXPECT_TRUE(manager.GetNameFromCommandPrecomposition(
PrecompositionState::IME_OFF, &name));
EXPECT_EQ("IMEOff", name);
EXPECT_TRUE(manager.GetNameFromCommandPrecomposition(
PrecompositionState::IME_ON, &name));
EXPECT_EQ("IMEOn", name);
EXPECT_TRUE(manager.GetNameFromCommandPrecomposition(
PrecompositionState::INSERT_CHARACTER, &name));
EXPECT_EQ("InsertCharacter", name);
EXPECT_TRUE(manager.GetNameFromCommandPrecomposition(
PrecompositionState::RECONVERT, &name));
EXPECT_EQ("Reconvert", name);
}
{
// Composition
string name;
EXPECT_TRUE(manager.GetNameFromCommandComposition(
CompositionState::IME_OFF, &name));
EXPECT_EQ("IMEOff", name);
EXPECT_TRUE(manager.GetNameFromCommandComposition(
CompositionState::IME_ON, &name));
EXPECT_EQ("IMEOn", name);
EXPECT_TRUE(manager.GetNameFromCommandComposition(
CompositionState::INSERT_CHARACTER, &name));
EXPECT_EQ("InsertCharacter", name);
}
{
// Conversion
string name;
EXPECT_TRUE(manager.GetNameFromCommandConversion(
ConversionState::IME_OFF, &name));
EXPECT_EQ("IMEOff", name);
EXPECT_TRUE(manager.GetNameFromCommandConversion(
ConversionState::IME_ON, &name));
EXPECT_EQ("IMEOn", name);
EXPECT_TRUE(manager.GetNameFromCommandConversion(
ConversionState::INSERT_CHARACTER, &name));
EXPECT_EQ("InsertCharacter", name);
}
}
TEST_F(KeyMapTest, DirectModeDoesNotSupportInsertSpace) {
// InsertSpace, InsertAlternateSpace, InsertHalfSpace, and InsertFullSpace
// are not supported in direct mode.
KeyMapManager manager;
set<string> names;
manager.GetAvailableCommandNameDirect(&names);
// We cannot use EXPECT_EQ because of overload resolution here.
EXPECT_TRUE(names.end() == names.find("InsertSpace"));
EXPECT_TRUE(names.end() == names.find("InsertAlternateSpace"));
EXPECT_TRUE(names.end() == names.find("InsertHalfSpace"));
EXPECT_TRUE(names.end() == names.find("InsertFullSpace"));
}
TEST_F(KeyMapTest, ShiftTabToConvertPrev) {
// http://b/2973471
// Shift+TAB does not work on a suggestion window
commands::KeyEvent key_event;
ConversionState::Commands conv_command;
{ // MSIME
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
KeyParser::ParseKey("Shift Tab", &key_event);
EXPECT_TRUE(manager->GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::CONVERT_PREV, conv_command);
}
{ // Kotoeri
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::KOTOERI);
KeyParser::ParseKey("Shift Tab", &key_event);
EXPECT_TRUE(manager->GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::CONVERT_PREV, conv_command);
}
{ // ATOK
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::ATOK);
KeyParser::ParseKey("Shift Tab", &key_event);
EXPECT_TRUE(manager->GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::CONVERT_PREV, conv_command);
}
}
TEST_F(KeyMapTest, LaunchToolTest) {
config::Config config;
commands::KeyEvent key_event;
PrecompositionState::Commands conv_command;
{ // ATOK
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::ATOK);
KeyParser::ParseKey("Ctrl F7", &key_event);
EXPECT_TRUE(manager->GetCommandPrecomposition(key_event, &conv_command));
EXPECT_EQ(PrecompositionState::LAUNCH_WORD_REGISTER_DIALOG, conv_command);
KeyParser::ParseKey("Ctrl F12", &key_event);
EXPECT_TRUE(manager->GetCommandPrecomposition(key_event, &conv_command));
EXPECT_EQ(PrecompositionState::LAUNCH_CONFIG_DIALOG, conv_command);
}
// http://b/3432829
// MS-IME does not have the key-binding "Ctrl F7" in precomposition mode.
{
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
KeyParser::ParseKey("Ctrl F7", &key_event);
EXPECT_FALSE(manager->GetCommandPrecomposition(key_event, &conv_command));
}
}
TEST_F(KeyMapTest, Undo) {
PrecompositionState::Commands command;
commands::KeyEvent key_event;
{ // ATOK
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::ATOK);
KeyParser::ParseKey("Ctrl Backspace", &key_event);
EXPECT_TRUE(manager->GetCommandPrecomposition(key_event, &command));
EXPECT_EQ(PrecompositionState::UNDO, command);
}
{ // MSIME
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
KeyParser::ParseKey("Ctrl Backspace", &key_event);
EXPECT_TRUE(manager->GetCommandPrecomposition(key_event, &command));
EXPECT_EQ(PrecompositionState::UNDO, command);
}
{ // KOTOERI
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::KOTOERI);
KeyParser::ParseKey("Ctrl Backspace", &key_event);
EXPECT_TRUE(manager->GetCommandPrecomposition(key_event, &command));
EXPECT_EQ(PrecompositionState::UNDO, command);
}
}
TEST_F(KeyMapTest, Reconvert) {
DirectInputState::Commands direct_command;
PrecompositionState::Commands precomposition_command;
commands::KeyEvent key_event;
{ // ATOK
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::ATOK);
KeyParser::ParseKey("Shift Henkan", &key_event);
EXPECT_TRUE(manager->GetCommandDirect(key_event, &direct_command));
EXPECT_EQ(DirectInputState::RECONVERT, direct_command);
EXPECT_TRUE(manager->GetCommandPrecomposition(
key_event, &precomposition_command));
EXPECT_EQ(PrecompositionState::RECONVERT, precomposition_command);
}
{ // MSIME
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
KeyParser::ParseKey("Henkan", &key_event);
EXPECT_TRUE(manager->GetCommandDirect(key_event, &direct_command));
EXPECT_EQ(DirectInputState::RECONVERT, direct_command);
EXPECT_TRUE(manager->GetCommandPrecomposition(
key_event, &precomposition_command));
EXPECT_EQ(PrecompositionState::RECONVERT, precomposition_command);
}
{ // KOTOERI
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::KOTOERI);
KeyParser::ParseKey("Ctrl Shift r", &key_event);
EXPECT_TRUE(manager->GetCommandDirect(key_event, &direct_command));
EXPECT_EQ(DirectInputState::RECONVERT, direct_command);
EXPECT_TRUE(manager->GetCommandPrecomposition(
key_event, &precomposition_command));
EXPECT_EQ(PrecompositionState::RECONVERT, precomposition_command);
}
}
TEST_F(KeyMapTest, ReloadWithKeymap) {
KeyMapManager manager;
config::Config::SessionKeymap keymap_setting;
commands::KeyEvent key_event;
ConversionState::Commands conv_command;
{ // ATOK
keymap_setting = config::Config::ATOK;
manager.ReloadWithKeymap(keymap_setting);
KeyParser::ParseKey("Right", &key_event);
EXPECT_TRUE(manager.GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::SEGMENT_WIDTH_EXPAND, conv_command);
}
{ // MSIME
keymap_setting = config::Config::MSIME;
manager.ReloadWithKeymap(keymap_setting);
KeyParser::ParseKey("Right", &key_event);
EXPECT_TRUE(manager.GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::SEGMENT_FOCUS_RIGHT, conv_command);
}
}
TEST_F(KeyMapTest, AddCommand) {
KeyMapManager manager;
commands::KeyEvent key_event;
const char kKeyEvent[] = "Ctrl Shift Insert";
KeyParser::ParseKey(kKeyEvent, &key_event);
{ // Add command
CompositionState::Commands command;
EXPECT_FALSE(manager.GetCommandComposition(key_event, &command));
EXPECT_TRUE(manager.AddCommand("Composition", kKeyEvent, "Cancel"));
EXPECT_TRUE(manager.GetCommandComposition(key_event, &command));
EXPECT_EQ(CompositionState::CANCEL, command);
}
{ // Error detections
EXPECT_FALSE(manager.AddCommand("void", kKeyEvent, "Cancel"));
EXPECT_FALSE(manager.AddCommand("Composition", kKeyEvent, "Unknown"));
EXPECT_FALSE(manager.AddCommand("Composition", "INVALID", "Cancel"));
}
}
TEST_F(KeyMapTest, ZeroQuerySuggestion) {
KeyMapManager manager;
EXPECT_TRUE(manager.AddCommand("ZeroQuerySuggestion",
"ESC", "Cancel"));
EXPECT_TRUE(manager.AddCommand("ZeroQuerySuggestion",
"Tab", "PredictAndConvert"));
EXPECT_TRUE(manager.AddCommand("ZeroQuerySuggestion",
"Shift Enter", "CommitFirstSuggestion"));
// For fallback testing
EXPECT_TRUE(manager.AddCommand("Precomposition", "Ctrl Backspace", "Revert"));
commands::KeyEvent key_event;
PrecompositionState::Commands command;
KeyParser::ParseKey("ESC", &key_event);
EXPECT_TRUE(manager.GetCommandZeroQuerySuggestion(key_event, &command));
EXPECT_EQ(PrecompositionState::CANCEL, command);
KeyParser::ParseKey("Tab", &key_event);
EXPECT_TRUE(manager.GetCommandZeroQuerySuggestion(key_event, &command));
EXPECT_EQ(PrecompositionState::PREDICT_AND_CONVERT, command);
KeyParser::ParseKey("Shift Enter", &key_event);
EXPECT_TRUE(manager.GetCommandZeroQuerySuggestion(key_event, &command));
EXPECT_EQ(PrecompositionState::COMMIT_FIRST_SUGGESTION, command);
KeyParser::ParseKey("Ctrl Backspace", &key_event);
EXPECT_TRUE(manager.GetCommandZeroQuerySuggestion(key_event, &command));
EXPECT_EQ(PrecompositionState::REVERT, command);
}
TEST_F(KeyMapTest, CapsLock) {
// MSIME
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
commands::KeyEvent key_event;
KeyParser::ParseKey("CAPS a", &key_event);
ConversionState::Commands conv_command;
EXPECT_TRUE(manager->GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::INSERT_CHARACTER, conv_command);
}
TEST_F(KeyMapTest, ShortcutKeysWithCapsLock_Issue5627459) {
// MSIME
KeyMapManager *manager =
KeyMapFactory::GetKeyMapManager(config::Config::MSIME);
commands::KeyEvent key_event;
CompositionState::Commands composition_command;
// "Ctrl CAPS H" means that Ctrl and H key are pressed w/o shift key.
// See the description in command.proto.
KeyParser::ParseKey("Ctrl CAPS H", &key_event);
EXPECT_TRUE(manager->GetCommandComposition(key_event, &composition_command));
EXPECT_EQ(CompositionState::BACKSPACE, composition_command);
// "Ctrl CAPS h" means that Ctrl, Shift and H key are pressed.
KeyParser::ParseKey("Ctrl CAPS h", &key_event);
EXPECT_FALSE(manager->GetCommandComposition(key_event, &composition_command));
}
// InputModeX is not supported on MacOSX.
TEST_F(KeyMapTest, InputModeChangeIsNotEnabledOnChromeOs_Issue13947207) {
if (!isInputModeXCommandSupported()) {
return;
}
KeyMapManager manager;
config::Config::SessionKeymap keymap_setting;
commands::KeyEvent key_event;
ConversionState::Commands conv_command;
{ // MSIME
keymap_setting = config::Config::MSIME;
manager.ReloadWithKeymap(keymap_setting);
KeyParser::ParseKey("Hiragana", &key_event);
EXPECT_TRUE(manager.GetCommandConversion(key_event, &conv_command));
EXPECT_EQ(ConversionState::INPUT_MODE_HIRAGANA, conv_command);
}
{ // CHROMEOS
keymap_setting = config::Config::CHROMEOS;
manager.ReloadWithKeymap(keymap_setting);
KeyParser::ParseKey("Hiragana", &key_event);
EXPECT_FALSE(manager.GetCommandConversion(key_event, &conv_command));
}
}
} // namespace keymap
} // namespace mozc