// Copyright 2010-2014, 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.

#include "session/session.h"

#include <string>
#include <vector>

#include "base/logging.h"
#include "base/system_util.h"
#include "base/util.h"
#include "composer/composer.h"
#include "composer/table.h"
#include "config/config.pb.h"
#include "config/config_handler.h"
#include "converter/conversion_request.h"
#include "converter/converter_mock.h"
#include "converter/segments.h"
#include "data_manager/user_pos_manager.h"
#include "engine/engine_interface.h"
#include "engine/mock_converter_engine.h"
#include "engine/mock_data_engine_factory.h"
#include "rewriter/transliteration_rewriter.h"
#include "session/candidates.pb.h"
#include "session/commands.pb.h"
#include "session/internal/ime_context.h"
#include "session/internal/keymap.h"
#include "session/key_parser.h"
#include "session/request_test_util.h"
#include "session/session_converter_interface.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"
#include "usage_stats/usage_stats.h"
#include "usage_stats/usage_stats_testing_util.h"

using ::mozc::commands::Request;
using ::mozc::usage_stats::UsageStats;

DECLARE_string(test_tmpdir);

namespace mozc {

class ConverterInterface;
class PredictorInterface;
class SuppressionDictionary;

namespace session {

namespace {
// "あいうえお"
const char kAiueo[] =
    "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A";
// "　"
const char kFullWidthSpace[] = "\xE3\x80\x80";
// "アイウエオ"
const char kKatakanaAiueo[] =
    "\xe3\x82\xa2\xe3\x82\xa4\xe3\x82\xa6\xe3\x82\xa8\xe3\x82\xaa";
// "あ"
const char kHiraganaA[] = "\xE3\x81\x82";
// "ａ"
const char kFullWidthSmallA[] = "\xEF\xBD\x81";

void SetSendKeyCommandWithKeyString(const string &key_string,
                                    commands::Command *command) {
  command->Clear();
  command->mutable_input()->set_type(commands::Input::SEND_KEY);
  commands::KeyEvent *key = command->mutable_input()->mutable_key();
  key->set_key_string(key_string);
}

bool SetSendKeyCommand(const string &key, commands::Command *command) {
  command->Clear();
  command->mutable_input()->set_type(commands::Input::SEND_KEY);
  return KeyParser::ParseKey(key, command->mutable_input()->mutable_key());
}

bool SendKey(const string &key,
             Session *session,
             commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  return session->SendKey(command);
}

bool SendKeyWithMode(const string &key,
                     commands::CompositionMode mode,
                     Session *session,
                     commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  command->mutable_input()->mutable_key()->set_mode(mode);
  return session->SendKey(command);
}

bool SendKeyWithModeAndActivated(const string &key,
                                 bool activated,
                                 commands::CompositionMode mode,
                                 Session *session,
                                 commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  command->mutable_input()->mutable_key()->set_activated(activated);
  command->mutable_input()->mutable_key()->set_mode(mode);
  return session->SendKey(command);
}

bool TestSendKey(const string &key,
                 Session *session,
                 commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  return session->TestSendKey(command);
}

bool TestSendKeyWithMode(const string &key,
                         commands::CompositionMode mode,
                         Session *session,
                         commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  command->mutable_input()->mutable_key()->set_mode(mode);
  return session->TestSendKey(command);
}

bool TestSendKeyWithModeAndActivated(const string &key,
                                     bool activated,
                                     commands::CompositionMode mode,
                                     Session *session,
                                     commands::Command *command) {
  if (!SetSendKeyCommand(key, command)) {
    return false;
  }
  command->mutable_input()->mutable_key()->set_activated(activated);
  command->mutable_input()->mutable_key()->set_mode(mode);
  return session->TestSendKey(command);
}

bool SendSpecialKey(commands::KeyEvent::SpecialKey special_key,
                    Session* session,
                    commands::Command* command) {
  command->Clear();
  command->mutable_input()->set_type(commands::Input::SEND_KEY);
  command->mutable_input()->mutable_key()->set_special_key(special_key);
  return session->SendKey(command);
}


void SetSendCommandCommand(commands::SessionCommand::CommandType type,
                           commands::Command *command) {
  command->Clear();
  command->mutable_input()->set_type(commands::Input::SEND_COMMAND);
  command->mutable_input()->mutable_command()->set_type(type);
}

bool SendCommand(commands::SessionCommand::CommandType type,
                 Session *session,
                 commands::Command *command) {
  SetSendCommandCommand(type, command);
  return session->SendCommand(command);
}

bool InsertCharacterCodeAndString(const char key_code,
                                  const string &key_string,
                                  Session *session,
                                  commands::Command *command) {
  command->Clear();
  commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
  key_event->set_key_code(key_code);
  key_event->set_key_string(key_string);
  return session->InsertCharacter(command);
}

Segment::Candidate *AddCandidate(const string &key, const string &value,
                                 Segment *segment) {
  Segment::Candidate *candidate = segment->add_candidate();
  candidate->key = key;
  candidate->content_key = key;
  candidate->value = value;
  return candidate;
}

Segment::Candidate *AddMetaCandidate(const string &key, const string &value,
                                     Segment *segment) {
  Segment::Candidate *candidate = segment->add_meta_candidate();
  candidate->key = key;
  candidate->content_key = key;
  candidate->value = value;
  return candidate;
}

string GetComposition(const commands::Command &command) {
  if (!command.output().has_preedit()) {
    return "";
  }

  string preedit;
  for (size_t i = 0; i < command.output().preedit().segment_size(); ++i) {
    preedit.append(command.output().preedit().segment(i).value());
  }
  return preedit;
}

::testing::AssertionResult EnsurePreedit(const string &expected,
                                         const commands::Command &command) {
  if (!command.output().has_preedit()) {
    return ::testing::AssertionFailure() << "No preedit.";
  }
  string actual;
  for (size_t i = 0; i < command.output().preedit().segment_size(); ++i) {
    actual.append(command.output().preedit().segment(i).value());
  }
  if (expected == actual) {
    return ::testing::AssertionSuccess();
  }
  return ::testing::AssertionFailure()
      << "expected: " << expected << ", actual: " << actual;
}

::testing::AssertionResult EnsureSingleSegment(
    const string &expected, const commands::Command &command) {
  if (!command.output().has_preedit()) {
    return ::testing::AssertionFailure() << "No preedit.";
  }
  if (command.output().preedit().segment_size() != 1) {
    return ::testing::AssertionFailure()
        << "Not single segment. segment size: "
        << command.output().preedit().segment_size();
  }
  const commands::Preedit::Segment &segment =
      command.output().preedit().segment(0);
  if (!segment.has_value()) {
    return ::testing::AssertionFailure() << "No segment value.";
  }
  const string &actual = segment.value();
  if (expected == actual) {
    return ::testing::AssertionSuccess();
  }
  return ::testing::AssertionFailure()
      << "expected: " << expected << ", actual: " << actual;
}

::testing::AssertionResult EnsureSingleSegmentAndKey(
    const string &expected_value,
    const string &expected_key,
    const commands::Command &command) {
  if (!command.output().has_preedit()) {
    return ::testing::AssertionFailure() << "No preedit.";
  }
  if (command.output().preedit().segment_size() != 1) {
    return ::testing::AssertionFailure()
        << "Not single segment. segment size: "
        << command.output().preedit().segment_size();
  }
  const commands::Preedit::Segment &segment =
      command.output().preedit().segment(0);
  if (!segment.has_value()) {
    return ::testing::AssertionFailure() << "No segment value.";
  }
  if (!segment.has_key()) {
    return ::testing::AssertionFailure() << "No segment key.";
  }
  const string &actual_value = segment.value();
  const string &actual_key = segment.key();
  if (expected_value == actual_value && expected_key == actual_key) {
    return ::testing::AssertionSuccess();
  }
  return ::testing::AssertionFailure()
      << "expected_value: " << expected_value
      << ", actual_value: " << actual_value
      << ", expected_key: " << expected_key
      << ", actual_key: " << actual_key;
}

::testing::AssertionResult EnsureResult(const string &expected,
                                        const commands::Command &command) {
  if (!command.output().has_result()) {
    return ::testing::AssertionFailure() << "No result.";
  }
  if (!command.output().result().has_value()) {
    return ::testing::AssertionFailure() << "No result value.";
  }
  const string &actual = command.output().result().value();
  if (expected == actual) {
    return ::testing::AssertionSuccess();
  }
  return ::testing::AssertionFailure()
      << "expected: " << expected << ", actual: " << actual;
}

::testing::AssertionResult EnsureResultAndKey(
    const string &expected_value,
    const string &expected_key,
    const commands::Command &command) {
  if (!command.output().has_result()) {
    return ::testing::AssertionFailure() << "No result.";
  }
  if (!command.output().result().has_value()) {
    return ::testing::AssertionFailure() << "No result value.";
  }
  if (!command.output().result().has_key()) {
    return ::testing::AssertionFailure() << "No result value.";
  }
  const string &actual_value = command.output().result().value();
  const string &actual_key = command.output().result().key();
  if (expected_value == actual_value && expected_key == actual_key) {
    return ::testing::AssertionSuccess();
  }
  return ::testing::AssertionFailure()
      << "expected_value: " << expected_value
      << ", actual_value: " << actual_value
      << ", expected_key: " << expected_key
      << ", actual_key: " << actual_key;
}

::testing::AssertionResult TryUndoAndAssertSuccess(Session *session) {
  commands::Command command;
  session->RequestUndo(&command);
  if (!command.output().consumed()) {
    return ::testing::AssertionFailure() << "Not consumed.";
  }
  if (!command.output().has_callback()) {
    return ::testing::AssertionFailure() << "No callback.";
  }
  if (command.output().callback().session_command().type() !=
      commands::SessionCommand::UNDO) {
    return ::testing::AssertionFailure() <<
        "Callback type is not Undo. Actual type: " <<
        command.output().callback().session_command().type();
  }
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult TryUndoAndAssertDoNothing(Session *session) {
  commands::Command command;
  session->RequestUndo(&command);
  if (command.output().consumed()) {
    return ::testing::AssertionFailure()
        << "Key event is consumed against expectation.";
  }
  return ::testing::AssertionSuccess();
}

#define EXPECT_PREEDIT(expected, command)  \
    EXPECT_TRUE(EnsurePreedit(expected, command))
#define EXPECT_SINGLE_SEGMENT(expected, command)  \
    EXPECT_TRUE(EnsureSingleSegment(expected, command))
#define EXPECT_SINGLE_SEGMENT_AND_KEY(expected_value, expected_key, command)  \
    EXPECT_TRUE(EnsureSingleSegmentAndKey(expected_value,                     \
                                          expected_key, command))
#define EXPECT_RESULT(expected, command)  \
    EXPECT_TRUE(EnsureResult(expected, command))
#define EXPECT_RESULT_AND_KEY(expected_value, expected_key, command)  \
    EXPECT_TRUE(EnsureResultAndKey(expected_value, expected_key, command))

void SetCaretLocation(const commands::Rectangle rectangle, Session *session) {
  commands::Command command;
  SetSendCommandCommand(commands::SessionCommand::SEND_CARET_LOCATION,
                        &command);
  command.mutable_input()->mutable_command()->mutable_caret_rectangle()->
      CopyFrom(rectangle);
  EXPECT_TRUE(session->SendCommand(&command));
}

void SwitchInputFieldType(commands::Context::InputFieldType type,
                          Session *session) {
  commands::Command command;
  SetSendCommandCommand(commands::SessionCommand::SWITCH_INPUT_FIELD_TYPE,
                        &command);
  command.mutable_input()->mutable_context()->set_input_field_type(type);
  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_EQ(type, session->context().composer().GetInputFieldType());
}

void SwitchInputMode(commands::CompositionMode mode, Session *session) {
  commands::Command command;
  SetSendCommandCommand(commands::SessionCommand::SWITCH_INPUT_MODE, &command);
  command.mutable_input()->mutable_command()->set_composition_mode(mode);
  EXPECT_TRUE(session->SendCommand(&command));
}

// since History segments are almost hidden from
class ConverterMockForReset : public ConverterMock {
 public:
  virtual bool ResetConversion(Segments *segments) const {
    reset_conversion_called_ = true;
    return true;
  }

  bool reset_conversion_called() const {
    return reset_conversion_called_;
  }

  void Reset() {
    reset_conversion_called_ = false;
  }

  ConverterMockForReset() : reset_conversion_called_(false) {}
 private:
  mutable bool reset_conversion_called_;
};

class MockConverterEngineForReset : public EngineInterface {
 public:
  MockConverterEngineForReset() : converter_mock_(new ConverterMockForReset) {}
  virtual ~MockConverterEngineForReset() {}

  virtual ConverterInterface *GetConverter() const {
    return converter_mock_.get();
  }

  virtual PredictorInterface *GetPredictor() const {
    return NULL;
  }

  virtual SuppressionDictionary *GetSuppressionDictionary() {
    return NULL;
  }

  virtual bool Reload() {
    return true;
  }

  virtual UserDataManagerInterface *GetUserDataManager() {
    return NULL;
  }

  const ConverterMockForReset &converter_mock() const {
    return *converter_mock_;
  }

  ConverterMockForReset *mutable_converter_mock() {
    return converter_mock_.get();
  }

 private:
  scoped_ptr<ConverterMockForReset> converter_mock_;
};

class ConverterMockForRevert : public ConverterMock {
 public:
  virtual bool RevertConversion(Segments *segments) const {
    revert_conversion_called_ = true;
    return true;
  }

  bool revert_conversion_called() const {
    return revert_conversion_called_;
  }

  void Reset() {
    revert_conversion_called_ = false;
  }

  ConverterMockForRevert() : revert_conversion_called_(false) {}
 private:
  mutable bool revert_conversion_called_;
};

class MockConverterEngineForRevert : public EngineInterface {
 public:
  MockConverterEngineForRevert()
      : converter_mock_(new ConverterMockForRevert) {}
  virtual ~MockConverterEngineForRevert() {}

  virtual ConverterInterface *GetConverter() const {
    return converter_mock_.get();
  }

  virtual PredictorInterface *GetPredictor() const {
    return NULL;
  }

  virtual SuppressionDictionary *GetSuppressionDictionary() {
    return NULL;
  }

  virtual bool Reload() {
    return true;
  }

  virtual UserDataManagerInterface *GetUserDataManager() {
    return NULL;
  }

  const ConverterMockForRevert &converter_mock() const {
    return *converter_mock_;
  }

  ConverterMockForRevert *mutable_converter_mock() {
    return converter_mock_.get();
  }

 private:
  scoped_ptr<ConverterMockForRevert> converter_mock_;
};

}  // namespace

class SessionTest : public testing::Test {
 protected:
  virtual void SetUp() {
    SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);

    config::Config config;
    config::ConfigHandler::GetDefaultConfig(&config);
    config::ConfigHandler::SetConfig(config);

    UsageStats::ClearAllStatsForTest();

    mobile_request_.reset(new Request);
    commands::RequestForUnitTest::FillMobileRequest(mobile_request_.get());

    mock_data_engine_.reset(MockDataEngineFactory::Create());
    engine_.reset(new MockConverterEngine);

    t13n_rewriter_.reset(
        new TransliterationRewriter(
            *UserPosManager::GetUserPosManager()->GetPOSMatcher()));
  }

  virtual void TearDown() {
    UsageStats::ClearAllStatsForTest();

    // just in case, reset the config in test_tmpdir
    config::Config config;
    config::ConfigHandler::GetDefaultConfig(&config);
    config::ConfigHandler::SetConfig(config);
  }

  void InsertCharacterChars(const string &chars,
                            Session *session,
                            commands::Command *command) const {
    const uint32 kNoModifiers = 0;
    for (int i = 0; i < chars.size(); ++i) {
      command->Clear();
      commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
      key_event->set_key_code(chars[i]);
      key_event->set_modifiers(kNoModifiers);
      session->InsertCharacter(command);
    }
  }

  void InsertCharacterCharsWithContext(const string &chars,
                                       const commands::Context &context,
                                       Session *session,
                                       commands::Command *command) const {
    const uint32 kNoModifiers = 0;
    for (size_t i = 0; i < chars.size(); ++i) {
      command->Clear();
      command->mutable_input()->mutable_context()->CopyFrom(context);
      commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
      key_event->set_key_code(chars[i]);
      key_event->set_modifiers(kNoModifiers);
      session->InsertCharacter(command);
    }
  }

  void InsertCharacterString(const string &key_strings,
                             const string &chars,
                             Session *session,
                             commands::Command *command) const {
    const uint32 kNoModifiers = 0;
    vector<string> inputs;
    const char *begin = key_strings.data();
    const char *end = key_strings.data() + key_strings.size();
    while (begin < end) {
      const size_t mblen = Util::OneCharLen(begin);
      inputs.push_back(string(begin, mblen));
      begin += mblen;
    }
    CHECK_EQ(inputs.size(), chars.size());
    for (int i = 0; i < chars.size(); ++i) {
      command->Clear();
      commands::KeyEvent *key_event = command->mutable_input()->mutable_key();
      key_event->set_key_code(chars[i]);
      key_event->set_modifiers(kNoModifiers);
      key_event->set_key_string(inputs[i]);
      session->InsertCharacter(command);
    }
  }

  // set result for "あいうえお"
  void SetAiueo(Segments *segments) {
    segments->Clear();
    Segment *segment;
    Segment::Candidate *candidate;

    segment = segments->add_segment();
    // "あいうえお"
    segment->set_key(kAiueo);
    candidate = segment->add_candidate();
    // "あいうえお"
    candidate->key = kAiueo;
    candidate->content_key = kAiueo;
    candidate->value = kAiueo;
    candidate = segment->add_candidate();
    // "アイウエオ"
    candidate->key = kAiueo;
    candidate->content_key = kAiueo;
    candidate->value = kKatakanaAiueo;
  }

  void InitSessionToDirect(Session* session) {
    InitSessionToPrecomposition(session);
    commands::Command command;
    session->IMEOff(&command);
  }

  void InitSessionToConversionWithAiueo(Session *session) {
    InitSessionToPrecomposition(session);

    commands::Command command;
    InsertCharacterChars("aiueo", session, &command);
    ConversionRequest request;
    Segments segments;
    SetComposer(session, &request);
    SetAiueo(&segments);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    EXPECT_TRUE(session->Convert(&command));
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());
  }

  void InitSessionToPrecomposition(Session* session) {
#ifdef OS_WIN
    // Session is created with direct mode on Windows
    // Direct status
    commands::Command command;
    session->IMEOn(&command);
#endif  // OS_WIN
    InitSessionWithRequest(session, commands::Request::default_instance());
  }

  void InitSessionToPrecomposition(
      Session* session,
      const commands::Request &request) {
#ifdef OS_WIN
    // Session is created with direct mode on Windows
    // Direct status
    commands::Command command;
    session->IMEOn(&command);
#endif  // OS_WIN
    InitSessionWithRequest(session, request);
  }

  void InitSessionWithRequest(
      Session* session,
      const commands::Request &request) {
    session->SetRequest(&request);
    table_.reset(new composer::Table());
    table_->InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session->SetTable(table_.get());
  }

  // set result for "like"
  void SetLike(Segments *segments) {
    Segment *segment;
    Segment::Candidate *candidate;

    segments->Clear();
    segment = segments->add_segment();

    // "ぃ"
    segment->set_key("\xE3\x81\x83");
    candidate = segment->add_candidate();
    // "ぃ"
    candidate->value = "\xE3\x81\x83";

    candidate = segment->add_candidate();
    // "ィ"
    candidate->value = "\xE3\x82\xA3";

    segment = segments->add_segment();
    // "け"
    segment->set_key("\xE3\x81\x91");
    candidate = segment->add_candidate();
    // "家"
    candidate->value = "\xE5\xAE\xB6";
    candidate = segment->add_candidate();
    // "け"
    candidate->value = "\xE3\x81\x91";
  }

  void FillT13Ns(const ConversionRequest &request, Segments *segments) {
    t13n_rewriter_->Rewrite(request, segments);
  }

  void SetComposer(Session *session, ConversionRequest *request) {
    DCHECK(request);
    request->set_composer(session->get_internal_composer_only_for_unittest());
  }

  void SetupMockForReverseConversion(const string &kanji,
                                     const string &hiragana) {
    // Set up Segments for reverse conversion.
    Segments reverse_segments;
    Segment *segment;
    segment = reverse_segments.add_segment();
    segment->set_key(kanji);
    Segment::Candidate *candidate;
    candidate = segment->add_candidate();
    // For reverse conversion, key is the original kanji string.
    candidate->key = kanji;
    candidate->value = hiragana;
    GetConverterMock()->SetStartReverseConversion(&reverse_segments, true);
    // Set up Segments for forward conversion.
    Segments segments;
    segment = segments.add_segment();
    segment->set_key(hiragana);
    candidate = segment->add_candidate();
    candidate->key = hiragana;
    candidate->value = kanji;
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  void SetupCommandForReverseConversion(const string &text,
                                        commands::Input *input) {
    input->Clear();
    input->set_type(commands::Input::SEND_COMMAND);
    input->mutable_command()->set_type(
        commands::SessionCommand::CONVERT_REVERSE);
    input->mutable_command()->set_text(text);
  }

  void SetupZeroQuerySuggestionReady(bool enable,
                                     Session *session,
                                     commands::Request *request) {
    InitSessionToPrecomposition(session);

    // Enable zero query suggest.
    request->set_zero_query_suggestion(enable);
    session->SetRequest(request);

    // Type "google".
    commands::Command command;
    InsertCharacterChars("google", session, &command);

    {
      // Set up a mock conversion result.
      Segments segments;
      segments.set_request_type(Segments::CONVERSION);
      Segment *segment;
      segment = segments.add_segment();
      segment->set_key("google");
      segment->add_candidate()->value = "GOOGLE";
      GetConverterMock()->SetStartConversionForRequest(&segments, true);
    }
    command.Clear();
    session->Convert(&command);

    {
      // Set up a mock suggestion result.
      Segments segments;
      segments.set_request_type(Segments::SUGGESTION);
      Segment *segment;
      segment = segments.add_segment();
      segment->set_key("");
      AddCandidate("search", "search", segment);
      AddCandidate("input", "input", segment);
      GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
    }
  }

  void SetupZeroQuerySuggestion(Session *session,
                                commands::Request *request,
                                commands::Command *command) {
    SetupZeroQuerySuggestionReady(true, session, request);
    command->Clear();
    session->Commit(command);
  }

  void SetUndoContext(Session *session) {
    commands::Command command;
    Segments segments;

    {  // Create segments
      InsertCharacterChars("aiueo", session, &command);
      SetAiueo(&segments);
      // Don't use FillT13Ns(). It makes platform dependent segments.
      // TODO(hsumita): Makes FillT13Ns() independent from platforms.
      Segment::Candidate *candidate;
      candidate = segments.mutable_segment(0)->add_candidate();
      candidate->value = "aiueo";
      candidate = segments.mutable_segment(0)->add_candidate();
      candidate->value = "AIUEO";
    }

    {  // Commit the composition to make an undo context.
      GetConverterMock()->SetStartConversionForRequest(&segments, true);
      command.Clear();
      session->Convert(&command);
      EXPECT_FALSE(command.output().has_result());
      // "あいうえお"
      EXPECT_PREEDIT(kAiueo, command);

      GetConverterMock()->SetCommitSegmentValue(&segments, true);
      command.Clear();
      session->Commit(&command);
      EXPECT_FALSE(command.output().has_preedit());
      // "あいうえお"
      EXPECT_RESULT(kAiueo, command);
    }
  }

  ConverterMock *GetConverterMock() {
    return engine_->mutable_converter_mock();
  }

  // IMPORTANT: Use scoped_ptr and instanciate an object in SetUp() method
  //    if the target object should be initialized *AFTER* global settings
  //    such as user profile dir or global config are set up for unit test.
  //    If you directly define a variable here without scoped_ptr, its
  //    constructor will be called *BEFORE* SetUp() is called.
  scoped_ptr<MockConverterEngine> engine_;
  scoped_ptr<EngineInterface> mock_data_engine_;
  scoped_ptr<TransliterationRewriter> t13n_rewriter_;
  scoped_ptr<composer::Table> table_;
  scoped_ptr<Request> mobile_request_;
  mozc::usage_stats::scoped_usage_stats_enabler usage_stats_enabler_;
};

// This test is intentionally defined at this location so that this
// test can ensure that the first SetUp() initialized global
// config, and table object to the default state.
// Please do not define another test before this.
// FYI, each TEST_F will be eventually expanded into a global variable
// and global variables in a single translation unit (source file) are
// always initialized in the order in which they are defined.
TEST_F(SessionTest, TestOfTestForSetup) {
  config::Config config;
  config::ConfigHandler::GetConfig(&config);
  EXPECT_FALSE(config.has_use_auto_conversion())
      << "Global config should be initialized for each text fixture.";

  // Make sure that the default roman table is initialized.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    SendKey("a", session.get(), &command);
    // "あ"
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command)
        << "Global Romaji table should be initialized for each text fixture.";
  }

  // intentionally leave non-default value so that |TestOfTestForTearDown|
  // can test it later.
  config.set_use_auto_conversion(true);
  config::ConfigHandler::SetConfig(config);
}

// This test ensures that the TearDown() against |TestOfTestForSetup|
// restored global config, and table object to the default state
// Please do not define another test between |TestOfTestForSetup| and
// this test.
// FYI, each TEST_F will be eventually expanded into a global variable
// and global variables in a single translation unit (source file) are
// always initialized in the order in which they are defined.
TEST_F(SessionTest, TestOfTestForTearDown) {
  // Make sure that the initial global config has default value.
  config::Config config;
  config::ConfigHandler::GetConfig(&config);
  EXPECT_FALSE(config.has_use_auto_conversion())
      << "Global config should be initialized for each text fixture.";

  // Make sure that the initial roman table has default value.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    SendKey("a", session.get(), &command);
    // "あ"
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command)
        << "Global Romaji table should be initialized for each text fixture.";
  }
}

TEST_F(SessionTest, TestSendKey) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;

  // Precomposition status
  TestSendKey("Up", session.get(), &command);
  EXPECT_FALSE(command.output().consumed());

  SendKey("Up", session.get(), &command);
  EXPECT_FALSE(command.output().consumed());

  // InsertSpace on Precomposition status
  // TODO(komatsu): Test both cases of GET_CONFIG(ascii_character_form) is
  // FULL_WIDTH and HALF_WIDTH after dependency injection of GET_CONFIG.
  TestSendKey("Space", session.get(), &command);
  const bool consumed_on_testsendkey = command.output().consumed();
  SendKey("Space", session.get(), &command);
  const bool consumed_on_sendkey = command.output().consumed();
  EXPECT_EQ(consumed_on_sendkey, consumed_on_testsendkey);

  // Precomposition status
  TestSendKey("G", session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  SendKey("G", session.get(), &command);
  EXPECT_TRUE(command.output().consumed());

  // Composition status
  TestSendKey("Up", session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  SendKey("Up", session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
}

TEST_F(SessionTest, SendCommand) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
  InsertCharacterChars("kanji", session.get(), &command);

  // REVERT
  SendCommand(commands::SessionCommand::REVERT, session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_candidates());

  // SUBMIT
  InsertCharacterChars("k", session.get(), &command);
  SendCommand(commands::SessionCommand::SUBMIT, session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  // "ｋ"
  EXPECT_RESULT("\xef\xbd\x8b", command);
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_candidates());

  // SWITCH_INPUT_MODE
  SendKey("a", session.get(), &command);
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  SwitchInputMode(commands::FULL_ASCII, session.get());

  SendKey("a", session.get(), &command);
  // "あａ"
  EXPECT_SINGLE_SEGMENT("\xE3\x81\x82\xEF\xBD\x81", command);

  // GET_STATUS
  SendCommand(commands::SessionCommand::GET_STATUS, session.get(), &command);
  // FULL_ASCII was set at the SWITCH_INPUT_MODE testcase.
  SwitchInputMode(commands::FULL_ASCII, session.get());

  // RESET_CONTEXT
  // test of reverting composition
  InsertCharacterChars("kanji", session.get(), &command);
  SendCommand(commands::SessionCommand::RESET_CONTEXT, session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_candidates());
  // test of reseting the history segements
  scoped_ptr<MockConverterEngineForReset> engine(
      new MockConverterEngineForReset);
  session.reset(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());
  SendCommand(commands::SessionCommand::RESET_CONTEXT, session.get(), &command);
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(engine->converter_mock().reset_conversion_called());

  // USAGE_STATS_EVENT
  SendCommand(commands::SessionCommand::USAGE_STATS_EVENT, session.get(),
              &command);
  EXPECT_TRUE(command.output().has_consumed());
  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, SwitchInputMode) {
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // SWITCH_INPUT_MODE
    SendKey("a", session.get(), &command);
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

    SwitchInputMode(commands::FULL_ASCII, session.get());

    SendKey("a", session.get(), &command);
    // "あａ"
    EXPECT_SINGLE_SEGMENT("\xE3\x81\x82\xEF\xBD\x81", command);

    // GET_STATUS
    SendCommand(commands::SessionCommand::GET_STATUS, session.get(), &command);
    // FULL_ASCII was set at the SWITCH_INPUT_MODE testcase.
    EXPECT_EQ(commands::FULL_ASCII, command.output().mode());
  }

  {
    // Confirm that we can change the mode from DIRECT
    // to other modes directly (without IMEOn command).
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;

    // GET_STATUS
    SendCommand(commands::SessionCommand::GET_STATUS, session.get(), &command);
    // FULL_ASCII was set at the SWITCH_INPUT_MODE testcase.
    EXPECT_EQ(commands::DIRECT, command.output().mode());

    // SWITCH_INPUT_MODE
    SwitchInputMode(commands::HIRAGANA, session.get());

    // GET_STATUS
    SendCommand(commands::SessionCommand::GET_STATUS, session.get(), &command);
    // FULL_ASCII was set at the SWITCH_INPUT_MODE testcase.
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    SendKey("a", session.get(), &command);
    // "あ"
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

    // GET_STATUS
    SendCommand(commands::SessionCommand::GET_STATUS, session.get(), &command);
    // FULL_ASCII was set at the SWITCH_INPUT_MODE testcase.
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }
}

TEST_F(SessionTest, RevertComposition) {
  // Issue#2237323
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  // REVERT
  SendCommand(commands::SessionCommand::REVERT, session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_candidates());

  SendKey("a", session.get(), &command);
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);
}

TEST_F(SessionTest, InputMode) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());

  SendKey("a", session.get(), &command);
  EXPECT_EQ("a", command.output().preedit().segment(0).key());

  command.Clear();
  session->Commit(&command);

  // Input mode remains even after submission.
  command.Clear();
  session->GetStatus(&command);
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());
}

TEST_F(SessionTest, SelectCandidate) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->ConvertNext(&command);

  SetSendCommandCommand(commands::SessionCommand::SELECT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(
      -(transliteration::HALF_KATAKANA + 1));
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_result());
  // "ｱｲｳｴｵ"
  EXPECT_PREEDIT(
      "\xEF\xBD\xB1\xEF\xBD\xB2\xEF\xBD\xB3\xEF\xBD\xB4\xEF\xBD\xB5", command);
  EXPECT_FALSE(command.output().has_candidates());
}

TEST_F(SessionTest, HighlightCandidate) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->ConvertNext(&command);
  // "アイウエオ"
  EXPECT_SINGLE_SEGMENT(
      "\xE3\x82\xA2\xE3\x82\xA4\xE3\x82\xA6\xE3\x82\xA8\xE3\x82\xAA", command);

  SetSendCommandCommand(commands::SessionCommand::HIGHLIGHT_CANDIDATE,
                        &command);
  command.mutable_input()->mutable_command()->set_id(
      -(transliteration::HALF_KATAKANA + 1));
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_result());
  // "ｱｲｳｴｵ"
  EXPECT_SINGLE_SEGMENT(
      "\xEF\xBD\xB1\xEF\xBD\xB2\xEF\xBD\xB3\xEF\xBD\xB4\xEF\xBD\xB5", command);
  EXPECT_TRUE(command.output().has_candidates());
}

TEST_F(SessionTest, Conversion) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  // "あいうえお"
  EXPECT_SINGLE_SEGMENT_AND_KEY(kAiueo, kAiueo, command);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->ConvertNext(&command);

  string key;
  for (int i = 0; i < command.output().preedit().segment_size(); ++i) {
    EXPECT_TRUE(command.output().preedit().segment(i).has_value());
    EXPECT_TRUE(command.output().preedit().segment(i).has_key());
    key += command.output().preedit().segment(i).key();
  }
  // "あいうえお"
  EXPECT_EQ(kAiueo, key);
}

TEST_F(SessionTest, SegmentWidthShrink) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->SegmentWidthShrink(&command);

  command.Clear();
  session->SegmentWidthShrink(&command);
}

TEST_F(SessionTest, ConvertPrev) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  Segments segments;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->ConvertNext(&command);

  command.Clear();
  session->ConvertPrev(&command);

  command.Clear();
  session->ConvertPrev(&command);
}

TEST_F(SessionTest, ResetFocusedSegmentAfterCommit) {
  ConversionRequest request;
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("watasinonamaehanakanodesu", session.get(), &command);
  // "わたしのなまえはなかのです[]"

  segment = segments.add_segment();
  // "わたしの"
  segment->set_key("\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae");
  candidate = segment->add_candidate();
  // "私の"
  candidate->value = "\xe7\xa7\x81\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "わたしの"
  candidate->value = "\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "渡しの"
  candidate->value = "\xe6\xb8\xa1\xe3\x81\x97\xe3\x81\xae";

  segment = segments.add_segment();
  // "なまえは"
  segment->set_key("\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x88\xe3\x81\xaf");
  candidate = segment->add_candidate();
  // "名前は"
  candidate->value = "\xe5\x90\x8d\xe5\x89\x8d\xe3\x81\xaf";
  candidate = segment->add_candidate();
  // "ナマエは"
  candidate->value = "\xe3\x83\x8a\xe3\x83\x9e\xe3\x82\xa8\xe3\x81\xaf";

  segment = segments.add_segment();
  // "なかのです"
  segment->set_key(
      "\xe3\x81\xaa\xe3\x81\x8b\xe3\x81\xae\xe3\x81\xa7\xe3\x81\x99");
  candidate = segment->add_candidate();
  // "中野です"
  candidate->value = "\xe4\xb8\xad\xe9\x87\x8e\xe3\x81\xa7\xe3\x81\x99";
  candidate = segment->add_candidate();
  // "なかのです"
  candidate->value
      = "\xe3\x81\xaa\xe3\x81\x8b\xe3\x81\xae\xe3\x81\xa7\xe3\x81\x99";
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  EXPECT_TRUE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  // "[私の]名前は中野です"
  command.Clear();
  session->SegmentFocusRight(&command);
  EXPECT_TRUE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  // "私の[名前は]中野です"
  command.Clear();
  session->SegmentFocusRight(&command);
  EXPECT_TRUE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  // "私の名前は[中野です]"

  command.Clear();
  session->ConvertNext(&command);
  EXPECT_EQ(1, command.output().candidates().focused_index());
  EXPECT_TRUE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  // "私の名前は[中のです]"

  command.Clear();
  session->ConvertNext(&command);
  EXPECT_EQ(2, command.output().candidates().focused_index());
  EXPECT_TRUE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  // "私の名前は[なかのです]"

  command.Clear();
  session->Commit(&command);
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_TRUE(command.output().has_result());
  // "私の名前はなかのです[]"

  InsertCharacterChars("a", session.get(), &command);

  segments.Clear();
  segment = segments.add_segment();
  // "あ"
  segment->set_key(kHiraganaA);
  candidate = segment->add_candidate();
  // "阿"
  candidate->value = "\xe9\x98\xbf";
  candidate = segment->add_candidate();
  // "亜"
  candidate->value = "\xe4\xba\x9c";

  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  // "あ[]"

  command.Clear();
  session->Convert(&command);
  // "[阿]"

  command.Clear();
  // If the forcused_segment_ was not reset, this raises segmentation fault.
  session->ConvertNext(&command);
  // "[亜]"
}

TEST_F(SessionTest, ResetFocusedSegmentAfterCancel) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("ai", session.get(), &command);

  segment = segments.add_segment();
  // "あい"
  segment->set_key("\xe3\x81\x82\xe3\x81\x84");
  candidate = segment->add_candidate();
  // "愛"
  candidate->value = "\xe6\x84\x9b";
  candidate = segment->add_candidate();
  // "相"
  candidate->value = "\xe7\x9b\xb8";
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);
  // "あい[]"

  command.Clear();
  session->Convert(&command);
  // "[愛]"

  segments.Clear();
  segment = segments.add_segment();
  // "あ"
  segment->set_key(kHiraganaA);
  candidate = segment->add_candidate();
  // "あ"
  candidate->value = kHiraganaA;
  segment = segments.add_segment();
  // "い"
  segment->set_key("\xe3\x81\x84");
  candidate = segment->add_candidate();
  // "い"
  candidate->value = "\xe3\x81\x84";
  candidate = segment->add_candidate();
  // "位"
  candidate->value = "\xe4\xbd\x8d";
  GetConverterMock()->SetResizeSegment1(&segments, true);

  command.Clear();
  session->SegmentWidthShrink(&command);
  // "[あ]い"

  segment = segments.mutable_segment(0);
  segment->set_segment_type(Segment::FIXED_VALUE);
  GetConverterMock()->SetCommitSegmentValue(&segments, true);

  command.Clear();
  session->SegmentFocusRight(&command);
  // "あ[い]"

  command.Clear();
  session->ConvertNext(&command);
  // "あ[位]"

  command.Clear();
  session->ConvertCancel(&command);
  // "あい[]"

  segments.Clear();
  segment = segments.add_segment();
  // "あい"
  segment->set_key("\xe3\x81\x82\xe3\x81\x84");
  candidate = segment->add_candidate();
  // "愛"
  candidate->value = "\xe6\x84\x9b";
  candidate = segment->add_candidate();
  // "相"
  candidate->value = "\xe7\x9b\xb8";
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  // "[愛]"

  command.Clear();
  // If the forcused_segment_ was not reset, this raises segmentation fault.
  session->Convert(&command);
  // "[相]"
}


TEST_F(SessionTest, KeepFixedCandidateAfterSegmentWidthExpand) {
  // Issue#1271099
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("bariniryokouniitta", session.get(), &command);
  // "ばりにりょこうにいった[]"

  segment = segments.add_segment();
  // "ばりに"
  segment->set_key("\xe3\x81\xb0\xe3\x82\x8a\xe3\x81\xab");
  candidate = segment->add_candidate();
  // "バリに"
  candidate->value = "\xe3\x83\x90\xe3\x83\xaa\xe3\x81\xab";
  candidate = segment->add_candidate();
  // "針に"
  candidate->value = "\xe9\x87\x9d\xe3\x81\xab";

  segment = segments.add_segment();
  // "りょこうに"
  segment->set_key(
      "\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x93\xe3\x81\x86\xe3\x81\xab");
  candidate = segment->add_candidate();
  // "旅行に"
  candidate->value = "\xe6\x97\x85\xe8\xa1\x8c\xe3\x81\xab";

  segment = segments.add_segment();
  // "いった"
  segment->set_key("\xe3\x81\x84\xe3\x81\xa3\xe3\x81\x9f");
  candidate = segment->add_candidate();
  // "行った"
  candidate->value = "\xe8\xa1\x8c\xe3\x81\xa3\xe3\x81\x9f";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  // ex. "[バリに]旅行に行った"
  EXPECT_EQ("\xE3\x83\x90\xE3\x83\xAA\xE3\x81\xAB\xE6\x97\x85\xE8\xA1\x8C\xE3"
      "\x81\xAB\xE8\xA1\x8C\xE3\x81\xA3\xE3\x81\x9F", GetComposition(command));
  command.Clear();
  session->ConvertNext(&command);
  // ex. "[針に]旅行に行った"
  const string first_segment = command.output().preedit().segment(0).value();

  segment = segments.mutable_segment(0);
  segment->set_segment_type(Segment::FIXED_VALUE);
  segment->move_candidate(1, 0);
  GetConverterMock()->SetCommitSegmentValue(&segments, true);

  command.Clear();
  session->SegmentFocusRight(&command);
  // ex. "針に[旅行に]行った"
  // Make sure the first segment (i.e. "針に" in the above case) remains
  // after moving the focused segment right.
  EXPECT_EQ(first_segment, command.output().preedit().segment(0).value());

  segment = segments.mutable_segment(1);
  // "りょこうにい"
  segment->set_key("\xe3\x82\x8a\xe3\x82\x87\xe3\x81\x93"
                   "\xe3\x81\x86\xe3\x81\xab\xe3\x81\x84");
  candidate = segment->mutable_candidate(0);
  // "旅行に行"
  candidate->value = "\xe6\x97\x85\xe8\xa1\x8c\xe3\x81\xab\xe8\xa1\x8c";

  segment = segments.mutable_segment(2);
  // "った"
  segment->set_key("\xe3\x81\xa3\xe3\x81\x9f");
  candidate = segment->mutable_candidate(0);
  // "った"
  candidate->value = "\xe3\x81\xa3\xe3\x81\x9f";

  GetConverterMock()->SetResizeSegment1(&segments, true);

  command.Clear();
  session->SegmentWidthExpand(&command);
  // ex. "針に[旅行に行]った"

  // Make sure the first segment (i.e. "針に" in the above case) remains
  // after expanding the focused segment.
  EXPECT_EQ(first_segment, command.output().preedit().segment(0).value());
}

TEST_F(SessionTest, CommitSegment) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;

  // Issue#1560608
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("watasinonamae", session.get(), &command);
  // "わたしのなまえ[]"

  segment = segments.add_segment();
  // "わたしの"
  segment->set_key("\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae");
  candidate = segment->add_candidate();
  // "私の"
  candidate->value = "\xe7\xa7\x81\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "わたしの"
  candidate->value = "\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "渡しの"
  candidate->value = "\xe6\xb8\xa1\xe3\x81\x97\xe3\x81\xae";

  segment = segments.add_segment();
  // "なまえ"
  segment->set_key("\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x88");
  candidate = segment->add_candidate();
  // "名前"
  candidate->value = "\xe5\x90\x8d\xe5\x89\x8d";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  // "[私の]名前"
  EXPECT_EQ(0, command.output().candidates().focused_index());

  command.Clear();
  session->ConvertNext(&command);
  // "[わたしの]名前"
  EXPECT_EQ(1, command.output().candidates().focused_index());

  command.Clear();
  session->ConvertNext(&command);
  // "[渡しの]名前" showing a candidate window
  EXPECT_EQ(2, command.output().candidates().focused_index());

  segment = segments.mutable_segment(0);
  segment->set_segment_type(Segment::FIXED_VALUE);
  segment->move_candidate(2, 0);

  GetConverterMock()->SetCommitSegments(&segments, true);

  command.Clear();
  session->CommitSegment(&command);
  // "渡しの" + "[名前]"
  EXPECT_EQ(0, command.output().candidates().focused_index());
}

TEST_F(SessionTest, CommitSegmentAt2ndSegment) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("watasinohaha", session.get(), &command);
  // "わたしのはは[]"

  segment = segments.add_segment();
  // "わたしの"
  segment->set_key("\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae");
  candidate = segment->add_candidate();
  // "私の"
  candidate->value = "\xe7\xa7\x81\xe3\x81\xae";
  segment = segments.add_segment();
  // "はは"
  segment->set_key("\xe3\x81\xaf\xe3\x81\xaf");
  candidate = segment->add_candidate();
  // "母"
  candidate->value = "\xe6\xaf\x8d";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  // "[私の]母"

  command.Clear();
  session->SegmentFocusRight(&command);
  // "私の[母]"

  segment->set_segment_type(Segment::FIXED_VALUE);
  segment->move_candidate(1, 0);
  GetConverterMock()->SetCommitSegments(&segments, true);

  command.Clear();
  session->CommitSegment(&command);
  // "私の" + "[母]"

  // "は"
  segment->set_key("\xe3\x81\xaf");
  // "葉"
  candidate->value = "\xe8\x91\x89";
  segment = segments.add_segment();
  // "は"
  segment->set_key("\xe3\x81\xaf");
  candidate = segment->add_candidate();
  // "は"
  candidate->value = "\xe3\x81\xaf";
  segments.pop_front_segment();
  GetConverterMock()->SetResizeSegment1(&segments, true);

  command.Clear();
  session->SegmentWidthShrink(&command);
  // "私の" + "[葉]は"
  EXPECT_EQ(2, command.output().preedit().segment_size());
}

TEST_F(SessionTest, Transliterations) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("jishin", session.get(), &command);

  segment = segments.add_segment();
  // "じしん"
  segment->set_key("\xe3\x81\x98\xe3\x81\x97\xe3\x82\x93");
  candidate = segment->add_candidate();
  // "自信"
  candidate->value = "\xe8\x87\xaa\xe4\xbf\xa1";
  candidate = segment->add_candidate();
  // "自身"
  candidate->value = "\xe8\x87\xaa\xe8\xba\xab";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  session->ConvertNext(&command);

  command.Clear();
  session->TranslateHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("jishin", command);

  command.Clear();
  session->TranslateHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("JISHIN", command);

  command.Clear();
  session->TranslateHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("Jishin", command);

  command.Clear();
  session->TranslateHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("jishin", command);
}

TEST_F(SessionTest, ConvertToTransliteration) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("jishin", session.get(), &command);

  segment = segments.add_segment();
  // "じしん"
  segment->set_key("\xe3\x81\x98\xe3\x81\x97\xe3\x82\x93");
  candidate = segment->add_candidate();
  // "自信"
  candidate->value = "\xe8\x87\xaa\xe4\xbf\xa1";
  candidate = segment->add_candidate();
  // "自身"
  candidate->value = "\xe8\x87\xaa\xe8\xba\xab";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("jishin", command);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("JISHIN", command);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("Jishin", command);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("jishin", command);
}

TEST_F(SessionTest, ConvertToTransliterationWithMultipleSegments) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("like", session.get(), &command);

  Segments segments;
  SetLike(&segments);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  // Convert
  command.Clear();
  session->Convert(&command);
  {  // Check the conversion #1
    const commands::Output &output = command.output();
    EXPECT_FALSE(output.has_result());
    EXPECT_TRUE(output.has_preedit());
    EXPECT_FALSE(output.has_candidates());

    const commands::Preedit &conversion = output.preedit();
    EXPECT_EQ(2, conversion.segment_size());
    // "ぃ"
    EXPECT_EQ("\xE3\x81\x83", conversion.segment(0).value());
    // "家"
    EXPECT_EQ("\xE5\xAE\xB6", conversion.segment(1).value());
  }

  // TranslateHalfASCII
  command.Clear();
  session->TranslateHalfASCII(&command);
  {  // Check the conversion #2
    const commands::Output &output = command.output();
    EXPECT_FALSE(output.has_result());
    EXPECT_TRUE(output.has_preedit());
    EXPECT_FALSE(output.has_candidates());

    const commands::Preedit &conversion = output.preedit();
    EXPECT_EQ(2, conversion.segment_size());
    EXPECT_EQ("li", conversion.segment(0).value());
  }
}

TEST_F(SessionTest, ConvertToHalfWidth) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("abc", session.get(), &command);

  Segments segments;
  {  // Initialize segments.
    Segment *segment = segments.add_segment();
    // "あｂｃ"
    segment->set_key("\xE3\x81\x82\xEF\xBD\x82\xEF\xBD\x83");
    // "あべし"
    segment->add_candidate()->value = "\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97";
  }
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->ConvertToHalfWidth(&command);
  // "ｱbc"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\xB1\x62\x63", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // The output is "ａｂｃ".

  command.Clear();
  session->ConvertToHalfWidth(&command);
  EXPECT_SINGLE_SEGMENT("abc", command);
}

TEST_F(SessionTest, ConvertConsonantsToFullAlphanumeric) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("dvd", session.get(), &command);

  segment = segments.add_segment();
  // "ｄｖｄ"
  segment->set_key("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84");
  candidate = segment->add_candidate();
  candidate->value = "DVD";
  candidate = segment->add_candidate();
  candidate->value = "dvd";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ＤＶＤ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBC\xA4\xEF\xBC\xB6\xEF\xBC\xA4", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "Ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBC\xA4\xEF\xBD\x96\xEF\xBD\x84", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84", command);
}

TEST_F(SessionTest, ConvertConsonantsToFullAlphanumericWithoutCascadingWindow) {
  config::Config config;
  config.set_use_cascading_window(false);
  config::ConfigHandler::SetConfig(config);

  commands::Command command;
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  InsertCharacterChars("dvd", session.get(), &command);

  segment = segments.add_segment();
  // "ｄｖｄ"
  segment->set_key("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84");
  candidate = segment->add_candidate();
  candidate->value = "DVD";
  candidate = segment->add_candidate();
  candidate->value = "dvd";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ＤＶＤ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBC\xA4\xEF\xBC\xB6\xEF\xBC\xA4", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "Ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBC\xA4\xEF\xBD\x96\xEF\xBD\x84", command);

  command.Clear();
  session->ConvertToFullASCII(&command);
  // "ｄｖｄ"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\x84\xEF\xBD\x96\xEF\xBD\x84", command);
}

// Convert input string to Hiragana, Katakana, and Half Katakana
TEST_F(SessionTest, SwitchKanaType) {
  {  // From composition mode.
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    InsertCharacterChars("abc", session.get(), &command);

    Segments segments;
    {  // Initialize segments.
      Segment *segment = segments.add_segment();
      // "あｂｃ"
      segment->set_key("\xE3\x81\x82\xEF\xBD\x82\xEF\xBD\x83");
      // "あべし"
      segment->add_candidate()->value = "\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97";
    }

    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    session->SwitchKanaType(&command);
    // "アｂｃ"
    EXPECT_SINGLE_SEGMENT("\xE3\x82\xA2\xEF\xBD\x82\xEF\xBD\x83", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "ｱbc"
    EXPECT_SINGLE_SEGMENT("\xEF\xBD\xB1\x62\x63", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "あｂｃ"
    EXPECT_SINGLE_SEGMENT("\xE3\x81\x82\xEF\xBD\x82\xEF\xBD\x83", command);

    command.Clear();
    session->SwitchKanaType(&command);
      // "アｂｃ"
    EXPECT_SINGLE_SEGMENT("\xE3\x82\xA2\xEF\xBD\x82\xEF\xBD\x83", command);
  }

  {  // From conversion mode.
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    InsertCharacterChars("kanji", session.get(), &command);

    Segments segments;
    {  // Initialize segments.
      Segment *segment = segments.add_segment();
      // "かんじ"
      segment->set_key("\xE3\x81\x8B\xE3\x82\x93\xE3\x81\x98");
      // "漢字"
      segment->add_candidate()->value = "\xE6\xBC\xA2\xE5\xAD\x97";
    }

    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    session->Convert(&command);
    // "漢字"
    EXPECT_SINGLE_SEGMENT("\xE6\xBC\xA2\xE5\xAD\x97", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "かんじ"
    EXPECT_SINGLE_SEGMENT("\xE3\x81\x8B\xE3\x82\x93\xE3\x81\x98", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "カンジ"
    EXPECT_SINGLE_SEGMENT("\xE3\x82\xAB\xE3\x83\xB3\xE3\x82\xB8", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "ｶﾝｼﾞ"
    EXPECT_SINGLE_SEGMENT(
        "\xEF\xBD\xB6\xEF\xBE\x9D\xEF\xBD\xBC\xEF\xBE\x9E", command);

    command.Clear();
    session->SwitchKanaType(&command);
    // "かんじ"
    EXPECT_SINGLE_SEGMENT("\xE3\x81\x8B\xE3\x82\x93\xE3\x81\x98", command);
  }
}

// Rotate input mode among Hiragana, Katakana, and Half Katakana
TEST_F(SessionTest, InputModeSwitchKanaType) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // HIRAGANA
  InsertCharacterChars("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());

  // HIRAGANA to FULL_KATAKANA
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeSwitchKanaType(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "ア"
  EXPECT_EQ("\xE3\x82\xA2", GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());

  // FULL_KATRAKANA to HALF_KATAKANA
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeSwitchKanaType(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "ｱ"
  EXPECT_EQ("\xEF\xBD\xB1",
            GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::HALF_KATAKANA, command.output().mode());

  // HALF_KATAKANA to HIRAGANA
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeSwitchKanaType(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());

  // To Half ASCII mode.
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeHalfASCII(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "a"
  EXPECT_EQ("a", GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  // HALF_ASCII to HALF_ASCII
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeSwitchKanaType(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "a"
  EXPECT_EQ("a", GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  // To Full ASCII mode.
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeFullASCII(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "ａ"
  EXPECT_EQ(kFullWidthSmallA, GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::FULL_ASCII, command.output().mode());

  // FULL_ASCII to FULL_ASCII
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->InputModeSwitchKanaType(&command);
  InsertCharacterChars("a", session.get(), &command);
  // "ａ"
  EXPECT_EQ(kFullWidthSmallA, GetComposition(command));
  EXPECT_TRUE(command.output().has_mode());
  EXPECT_EQ(commands::FULL_ASCII, command.output().mode());
}

TEST_F(SessionTest, TranslateHalfWidth) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("abc", session.get(), &command);

  command.Clear();
  session->TranslateHalfWidth(&command);
  // "ｱbc"
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\xB1\x62\x63", command);

  command.Clear();
  session->TranslateFullASCII(&command);
  // "ａｂｃ".
  EXPECT_SINGLE_SEGMENT("\xEF\xBD\x81\xEF\xBD\x82\xEF\xBD\x83", command);

  command.Clear();
  session->TranslateHalfWidth(&command);
  EXPECT_SINGLE_SEGMENT("abc", command);
}

TEST_F(SessionTest, UpdatePreferences) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);
  Segments segments;
  SetAiueo(&segments);

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);

  SetSendKeyCommand("SPACE", &command);
  command.mutable_input()->mutable_config()->set_use_cascading_window(false);
  session->SendKey(&command);
  const size_t no_cascading_cand_size =
      command.output().candidates().candidate_size();

  command.Clear();
  session->ConvertCancel(&command);

  SetSendKeyCommand("SPACE", &command);
  command.mutable_input()->mutable_config()->set_use_cascading_window(true);
  session->SendKey(&command);
  const size_t cascading_cand_size =
      command.output().candidates().candidate_size();

  EXPECT_GT(no_cascading_cand_size, cascading_cand_size);

  command.Clear();
  session->ConvertCancel(&command);

  // On MS-IME keymap, EISU key does nothing.
  SetSendKeyCommand("EISU", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MSIME);
  session->SendKey(&command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
  EXPECT_EQ(commands::HALF_ASCII, command.output().status().comeback_mode());

  // On KOTOERI keymap, EISU key does "ToggleAlphanumericMode".
  SetSendKeyCommand("EISU", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::KOTOERI);
  session->SendKey(&command);
  EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
  EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
}

TEST_F(SessionTest, RomajiInput) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  composer::Table table;
  // "ぱ"
  table.AddRule("pa", "\xe3\x81\xb1", "");
  // "ん"
  table.AddRule("n", "\xe3\x82\x93", "");
  // "な"
  table.AddRule("na", "\xe3\x81\xaa", "");
  // This rule makes the "n" rule ambiguous.

  scoped_ptr<Session> session(new Session(engine_.get()));
  session->get_internal_composer_only_for_unittest()->SetTable(&table);
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("pan", session.get(), &command);

  // "ぱｎ"
  EXPECT_EQ("\xe3\x81\xb1\xef\xbd\x8e",
            command.output().preedit().segment(0).value());

  command.Clear();

  segment = segments.add_segment();
  // "ぱん"
  segment->set_key("\xe3\x81\xb1\xe3\x82\x93");
  candidate = segment->add_candidate();
  // "パン"
  candidate->value = "\xe3\x83\x91\xe3\x83\xb3";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  session->ConvertToHiragana(&command);
  // "ぱん"
  EXPECT_SINGLE_SEGMENT("\xe3\x81\xb1\xe3\x82\x93", command);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("pan", command);
}


TEST_F(SessionTest, KanaInput) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  composer::Table table;
  // "す゛", "ず"
  table.AddRule("\xe3\x81\x99\xe3\x82\x9b", "\xe3\x81\x9a", "");

  scoped_ptr<Session> session(new Session(engine_.get()));
  session->get_internal_composer_only_for_unittest()->SetTable(&table);
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  SetSendKeyCommand("m", &command);
  // "も"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x82\x82");
  session->SendKey(&command);

  SetSendKeyCommand("r", &command);
  // "す"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x81\x99");
  session->SendKey(&command);

  SetSendKeyCommand("@", &command);
  // "゛"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x82\x9b");
  session->SendKey(&command);

  SetSendKeyCommand("h", &command);
  // "く"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x81\x8f");
  session->SendKey(&command);

  SetSendKeyCommand("!", &command);
  command.mutable_input()->mutable_key()->set_key_string("!");
  session->SendKey(&command);

  // "もずく！"
  EXPECT_EQ("\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f\xef\xbc\x81",
            command.output().preedit().segment(0).value());

  segment = segments.add_segment();
  // "もずく!"
  segment->set_key("\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f!");
  candidate = segment->add_candidate();
  // "もずく！"
  candidate->value = "\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f\xef\xbc\x81";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->ConvertToHalfASCII(&command);
  EXPECT_SINGLE_SEGMENT("mr@h!", command);
}

TEST_F(SessionTest, ExceededComposition) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  const string exceeded_preedit(500, 'a');
  ASSERT_EQ(500, exceeded_preedit.size());
  InsertCharacterChars(exceeded_preedit, session.get(), &command);

  string long_a;
  for (int i = 0; i < 500; ++i) {
    // "あ"
    long_a += kHiraganaA;
  }
  segment = segments.add_segment();
  segment->set_key(long_a);
  candidate = segment->add_candidate();
  candidate->value = long_a;

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  EXPECT_FALSE(command.output().has_candidates());

  // The status should remain the preedit status, although the
  // previous command was convert.  The next command makes sure that
  // the preedit will disappear by canceling the preedit status.
  command.Clear();
  command.mutable_input()->mutable_key()->set_special_key(
      commands::KeyEvent::ESCAPE);
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, OutputAllCandidateWords) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  Segments segments;
  SetAiueo(&segments);
  InsertCharacterChars("aiueo", session.get(), &command);

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  {
    const commands::Output &output = command.output();
    EXPECT_TRUE(output.has_all_candidate_words());

    EXPECT_EQ(0, output.all_candidate_words().focused_index());
    EXPECT_EQ(commands::CONVERSION, output.all_candidate_words().category());
#ifdef OS_LINUX
    // Cascading window is not supported on Linux, so the size of
    // candidate words is different from other platform.
    // TODO(komatsu): Modify the client for Linux to explicitly change
    // the preference rather than relying on the exceptional default value.
    // [ "あいうえお", "アイウエオ",
    //   "aiueo" (t13n), "AIUEO" (t13n), "Aieuo" (t13n),
    //   "ａｉｕｅｏ"  (t13n), "ＡＩＵＥＯ" (t13n), "Ａｉｅｕｏ" (t13n),
    //   "ｱｲｳｴｵ" (t13n) ]
    EXPECT_EQ(9, output.all_candidate_words().candidates_size());
#else
    // [ "あいうえお", "アイウエオ", "アイウエオ" (t13n), "あいうえお" (t13n),
    //   "aiueo" (t13n), "AIUEO" (t13n), "Aieuo" (t13n),
    //   "ａｉｕｅｏ"  (t13n), "ＡＩＵＥＯ" (t13n), "Ａｉｅｕｏ" (t13n),
    //   "ｱｲｳｴｵ" (t13n) ]
    EXPECT_EQ(11, output.all_candidate_words().candidates_size());
#endif  // OS_LINUX
  }

  command.Clear();
  session->ConvertNext(&command);
  {
    const commands::Output &output = command.output();

    EXPECT_TRUE(output.has_all_candidate_words());

    EXPECT_EQ(1, output.all_candidate_words().focused_index());
    EXPECT_EQ(commands::CONVERSION, output.all_candidate_words().category());
#ifdef OS_LINUX
    // Cascading window is not supported on Linux, so the size of
    // candidate words is different from other platform.
    // TODO(komatsu): Modify the client for Linux to explicitly change
    // the preference rather than relying on the exceptional default value.
    // [ "あいうえお", "アイウエオ", "アイウエオ" (t13n), "あいうえお" (t13n),
    //   "aiueo" (t13n), "AIUEO" (t13n), "Aieuo" (t13n),
    //   "ａｉｕｅｏ"  (t13n), "ＡＩＵＥＯ" (t13n), "Ａｉｅｕｏ" (t13n),
    //   "ｱｲｳｴｵ" (t13n) ]
    EXPECT_EQ(9, output.all_candidate_words().candidates_size());
#else
    // [ "あいうえお", "アイウエオ",
    //   "aiueo" (t13n), "AIUEO" (t13n), "Aieuo" (t13n),
    //   "ａｉｕｅｏ"  (t13n), "ＡＩＵＥＯ" (t13n), "Ａｉｅｕｏ" (t13n),
    //   "ｱｲｳｴｵ" (t13n) ]
    EXPECT_EQ(11, output.all_candidate_words().candidates_size());
#endif  // OS_LINUX
  }
}

TEST_F(SessionTest, UndoForComposition) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  // Enable zero query suggest.
  commands::Request request;
  SetupZeroQuerySuggestionReady(true, &session, &request);

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session.set_client_capability(capability);

  commands::Command command;
  Segments segments;
  Segments empty_segments;

  {  // Undo for CommitFirstSuggestion
    SetAiueo(&segments);
    GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
    InsertCharacterChars("ai", &session, &command);
    ConversionRequest request;
    SetComposer(&session, &request);
    // "あい"
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84", GetComposition(command));

    command.Clear();
    GetConverterMock()->SetFinishConversion(&empty_segments, true);
    session.CommitFirstSuggestion(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());

    command.Clear();
    session.Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "あい"
    EXPECT_SINGLE_SEGMENT("\xE3\x81\x82\xE3\x81\x84", command);
    EXPECT_EQ(2, command.output().candidates().size());
    EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());
  }
}

TEST_F(SessionTest, RequestUndo) {
  scoped_ptr<Session> session(new Session(engine_.get()));

  // It is OK not to check ImeContext::DIRECT because you cannot
  // assign any key event to Undo command in DIRECT mode.
  // See "session/internal/keymap_interface.h".

  InitSessionToPrecomposition(session.get());
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()))
      << "When the UNDO context is empty and the context state is "
         "ImeContext::PRECOMPOSITION, UNDO command should be "
         "ignored. See b/5553298.";

  InitSessionToPrecomposition(session.get());
  SetUndoContext(session.get());
  EXPECT_TRUE(TryUndoAndAssertSuccess(session.get()));

  InitSessionToPrecomposition(session.get());
  SetUndoContext(session.get());
  session->context_->set_state(ImeContext::COMPOSITION);
  EXPECT_TRUE(TryUndoAndAssertSuccess(session.get()));

  InitSessionToPrecomposition(session.get());
  SetUndoContext(session.get());
  session->context_->set_state(ImeContext::CONVERSION);
  EXPECT_TRUE(TryUndoAndAssertSuccess(session.get()));
}

TEST_F(SessionTest, UndoForSingleSegment) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  commands::Command command;
  Segments segments;

  {  // Create segments
    InsertCharacterChars("aiueo", session.get(), &command);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    SetAiueo(&segments);
    // Don't use FillT13Ns(). It makes platform dependent segments.
    // TODO(hsumita): Makes FillT13Ns() independent from platforms.
    Segment::Candidate *candidate;
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "aiueo";
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "AIUEO";
  }

  {  // Undo after commitment of composition
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);

    // Undo twice - do nothing and keep the previous status.
    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_deletion_range());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);
  }

  {  // Undo after commitment of conversion
    command.Clear();
    session->ConvertNext(&command);
    EXPECT_FALSE(command.output().has_result());
    // "アイウエオ"
    EXPECT_PREEDIT(kKatakanaAiueo, command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "アイウエオ"
    EXPECT_RESULT(kKatakanaAiueo, command);

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "アイウエオ"
    EXPECT_PREEDIT(kKatakanaAiueo, command);

    // Undo twice - do nothing and keep the previous status.
    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_deletion_range());
    // "アイウエオ"
    EXPECT_PREEDIT(kKatakanaAiueo, command);
  }

  {  // Undo after commitment of conversion with Ctrl-Backspace.
    command.Clear();
    session->ConvertNext(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_PREEDIT("aiueo", command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_RESULT("aiueo", command);

    config::Config config;
    config.set_session_keymap(config::Config::MSIME);
    config::ConfigHandler::SetConfig(config);

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    EXPECT_PREEDIT("aiueo", command);
  }

  {
    // If capability does not support DELETE_PRECEDIGN_TEXT, Undo is not
    // performed.
    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_RESULT("aiueo", command);

    // Reset capability
    capability.Clear();
    session->set_client_capability(capability);

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_deletion_range());
    EXPECT_FALSE(command.output().has_preedit());
  }
}

TEST_F(SessionTest, ClearUndoContextByKeyEvent_Issue5529702) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  SetUndoContext(session.get());

  commands::Command command;

  // Modifier key event does not clear undo context.
  SendKey("Shift", session.get(), &command);

  // Ctrl+BS should be consumed as UNDO.
  SetSendKeyCommand("Ctrl Backspace", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MSIME);
  session->TestSendKey(&command);
  EXPECT_TRUE(command.output().consumed());

  // Any other (test) send key event clears undo context.
  TestSendKey("LEFT", session.get(), &command);
  EXPECT_FALSE(command.output().consumed());

  // Undo context is just cleared. Ctrl+BS should not be consumed b/5553298.
  SetSendKeyCommand("Ctrl Backspace", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MSIME);
  session->TestSendKey(&command);
  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, UndoForMultipleSegments) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  commands::Command command;
  Segments segments;

  {  // Create segments
    InsertCharacterChars("key1key2key3", session.get(), &command);
    ConversionRequest request;
    SetComposer(session.get(), &request);

    Segment::Candidate *candidate;
    Segment *segment;

    segment = segments.add_segment();
    segment->set_key("key1");
    candidate = segment->add_candidate();
    candidate->value = "cand1-1";
    candidate = segment->add_candidate();
    candidate->value = "cand1-2";

    segment = segments.add_segment();
    segment->set_key("key2");
    candidate = segment->add_candidate();
    candidate->value = "cand2-1";
    candidate = segment->add_candidate();
    candidate->value = "cand2-2";

    segment = segments.add_segment();
    segment->set_key("key3");
    candidate = segment->add_candidate();
    candidate->value = "cand3-1";
    candidate = segment->add_candidate();
    candidate->value = "cand3-2";
  }

  {  // Undo for CommitCandidate
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    command.mutable_input()->mutable_command()->set_id(1);
    session->CommitCandidate(&command);
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_RESULT("cand1-2", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-7, command.output().deletion_range().offset());
    EXPECT_EQ(7, command.output().deletion_range().length());
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    // Move to second segment and do the same thing.
    command.Clear();
    session->SegmentFocusRight(&command);
    command.Clear();
    command.mutable_input()->mutable_command()->set_id(1);
    session->CommitCandidate(&command);
    // "cand2-2" is focused
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_RESULT("cand1-1cand2-2", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-14, command.output().deletion_range().offset());
    EXPECT_EQ(14, command.output().deletion_range().length());
    // "cand2-1" is focused
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());
  }
  {  // Undo for CommitSegment
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->ConvertNext(&command);
    EXPECT_EQ("cand1-2cand2-1cand3-1", GetComposition(command));
    command.Clear();
    session->CommitSegment(&command);
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_RESULT("cand1-2", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-7, command.output().deletion_range().offset());
    EXPECT_EQ(7, command.output().deletion_range().length());
    EXPECT_PREEDIT("cand1-2cand2-1cand3-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    // Move to third segment and do the same thing.
    command.Clear();
    session->SegmentFocusRight(&command);
    command.Clear();
    session->SegmentFocusRight(&command);
    command.Clear();
    session->ConvertNext(&command);
    EXPECT_PREEDIT("cand1-1cand2-1cand3-2", command);
    command.Clear();
    session->CommitSegment(&command);
    // "cand3-2" is focused
    EXPECT_PREEDIT("cand1-1cand2-1cand3-1", command);
    EXPECT_RESULT("cand1-1", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-7, command.output().deletion_range().offset());
    EXPECT_EQ(7, command.output().deletion_range().length());
    // "cand3-2" is focused
    EXPECT_PREEDIT("cand1-1cand2-1cand3-2", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());
  }
}

TEST_F(SessionTest, UndoOrRewind_undo) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);


  // Commit twice.
  for (size_t i = 0; i < 2; ++i) {
    commands::Command command;
    Segments segments;
    {  // Create segments
      InsertCharacterChars("aiueo", session.get(), &command);
      ConversionRequest request;
      SetComposer(session.get(), &request);
      SetAiueo(&segments);
      Segment::Candidate *candidate;
      candidate = segments.mutable_segment(0)->add_candidate();
      candidate->value = "aiueo";
      candidate = segments.mutable_segment(0)->add_candidate();
      candidate->value = "AIUEO";
    }
    {
      GetConverterMock()->SetStartConversionForRequest(&segments, true);
      command.Clear();
      session->Convert(&command);
      EXPECT_FALSE(command.output().has_result());
      // "あいうえお"
      EXPECT_PREEDIT(kAiueo, command);

      GetConverterMock()->SetCommitSegmentValue(&segments, true);
      command.Clear();
      session->Commit(&command);
      EXPECT_FALSE(command.output().has_preedit());
      // "あいうえお"
      EXPECT_RESULT(kAiueo, command);
    }
  }
  // Try UndoOrRewind twice.
  // Second trial should not return deletation_range.
  commands::Command command;
  command.Clear();
  session->UndoOrRewind(&command);
  EXPECT_FALSE(command.output().has_result());
  // "あいうえお"
  EXPECT_PREEDIT(kAiueo, command);
  EXPECT_TRUE(command.output().has_deletion_range());
  command.Clear();
  session->UndoOrRewind(&command);
  EXPECT_FALSE(command.output().has_result());
  // "あいうえお"
  EXPECT_PREEDIT(kAiueo, command);
  EXPECT_FALSE(command.output().has_deletion_range());
}

TEST_F(SessionTest, UndoOrRewind_rewind) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get(), *mobile_request_);

  Segments segments;
  {
    segments.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments.add_segment();
    AddCandidate("e", "e", segment);
    AddCandidate("e", "E", segment);
  }
  GetConverterMock()->SetStartSuggestionForRequest(&segments, true);

  commands::Command command;
  InsertCharacterChars("11111", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  // "お"
  EXPECT_PREEDIT("\xE3\x81\x8A", command);
  EXPECT_FALSE(command.output().has_deletion_range());
  EXPECT_TRUE(command.output().has_all_candidate_words());

  command.Clear();
  session->UndoOrRewind(&command);
  EXPECT_FALSE(command.output().has_result());
  // "え"
  EXPECT_PREEDIT("\xE3\x81\x88", command);
  EXPECT_FALSE(command.output().has_deletion_range());
  EXPECT_TRUE(command.output().has_all_candidate_words());
}

TEST_F(SessionTest, CommitRawText) {
  {  // From composition mode.
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    InsertCharacterChars("abc", session.get(), &command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());

    Segments segments;
    {  // Initialize segments.
      Segment *segment = segments.add_segment();
      // "あｂｃ"
      segment->set_key("\xE3\x81\x82\xEF\xBD\x82\xEF\xBD\x83");
      // "あべし"
      segment->add_candidate()->value = "\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97";
    }

    command.Clear();
    SetSendCommandCommand(commands::SessionCommand::COMMIT_RAW_TEXT, &command);
    session->SendCommand(&command);
    // "abc"
    EXPECT_RESULT_AND_KEY("abc", "abc", command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
  }
  {  // From conversion mode.
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    InsertCharacterChars("abc", session.get(), &command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());

    Segments segments;
    {  // Initialize segments.
      Segment *segment = segments.add_segment();
      // "あｂｃ"
      segment->set_key("\xE3\x81\x82\xEF\xBD\x82\xEF\xBD\x83");
      // "あべし"
      segment->add_candidate()->value = "\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97";
    }

    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    // "あべし"
    EXPECT_PREEDIT("\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97", command);
    EXPECT_EQ(ImeContext::CONVERSION, session->context().state());

    command.Clear();
    SetSendCommandCommand(commands::SessionCommand::COMMIT_RAW_TEXT, &command);
    session->SendCommand(&command);
    // "abc"
    EXPECT_RESULT_AND_KEY("abc", "abc", command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
  }
}

TEST_F(SessionTest, CommitRawText_KanaInput) {
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  composer::Table table;
  // "す゛", "ず"
  table.AddRule("\xe3\x81\x99\xe3\x82\x9b", "\xe3\x81\x9a", "");

  scoped_ptr<Session> session(new Session(engine_.get()));
  session->get_internal_composer_only_for_unittest()->SetTable(&table);
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  SetSendKeyCommand("m", &command);
  // "も"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x82\x82");
  session->SendKey(&command);

  SetSendKeyCommand("r", &command);
  // "す"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x81\x99");
  session->SendKey(&command);

  SetSendKeyCommand("@", &command);
  // "゛"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x82\x9b");
  session->SendKey(&command);

  SetSendKeyCommand("h", &command);
  // "く"
  command.mutable_input()->mutable_key()->set_key_string("\xe3\x81\x8f");
  session->SendKey(&command);

  SetSendKeyCommand("!", &command);
  command.mutable_input()->mutable_key()->set_key_string("!");
  session->SendKey(&command);

  // "もずく！"
  EXPECT_EQ("\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f\xef\xbc\x81",
            command.output().preedit().segment(0).value());

  segment = segments.add_segment();
  // "もずく!"
  segment->set_key("\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f!");
  candidate = segment->add_candidate();
  // "もずく！"
  candidate->value = "\xe3\x82\x82\xe3\x81\x9a\xe3\x81\x8f\xef\xbc\x81";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  SetSendCommandCommand(commands::SessionCommand::COMMIT_RAW_TEXT, &command);
  session->SendCommand(&command);
  // "abc"
  EXPECT_RESULT_AND_KEY("mr@h!", "mr@h!", command);
  EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
}

TEST_F(SessionTest, ConvertNextPage_PrevPage) {
  commands::Command command;
  scoped_ptr<Session> session(new Session(engine_.get()));

  InitSessionToPrecomposition(session.get());

  // Should be ignored in precomposition state.
  {
    command.Clear();
    command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
    command.mutable_input()->mutable_command()->set_type(
        commands::SessionCommand::CONVERT_NEXT_PAGE);
    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());

    command.Clear();
    command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
    command.mutable_input()->mutable_command()->set_type(
        commands::SessionCommand::CONVERT_PREV_PAGE);
    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
  }

  InsertCharacterChars("aiueo", session.get(), &command);
  EXPECT_PREEDIT(kAiueo, command);

  // Should be ignored in composition state.
  {
    command.Clear();
    command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
    command.mutable_input()->mutable_command()->set_type(
        commands::SessionCommand::CONVERT_NEXT_PAGE);
    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_PREEDIT(kAiueo, command) << "should do nothing";

    command.Clear();
    command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
    command.mutable_input()->mutable_command()->set_type(
        commands::SessionCommand::CONVERT_PREV_PAGE);
    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_PREEDIT(kAiueo, command) << "should do nothing";
  }

  // Generate sequential candidates as follows.
  //   "page0-cand0"
  //   "page0-cand1"
  //   ...
  //   "page0-cand8"
  //   "page1-cand0"
  //   ...
  //   "page1-cand8"
  //   "page2-cand0"
  //   ...
  //   "page2-cand8"
  {
    Segments segments;
    Segment *segment = NULL;
    segment = segments.add_segment();
    segment->set_key(kAiueo);
    for (int page_index = 0; page_index < 3; ++page_index) {
      for (int cand_index = 0; cand_index < 9; ++cand_index) {
        segment->add_candidate()->value = Util::StringPrintf(
            "page%d-cand%d", page_index, cand_index);
      }
    }
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  // Make sure the selected candidate changes as follows.
  //                              -> Convert
  //  -> "page0-cand0" -> SendCommand/CONVERT_NEXT_PAGE
  //  -> "page1-cand0" -> SendCommand/CONVERT_PREV_PAGE
  //  -> "page0-cand0" -> SendCommand/CONVERT_PREV_PAGE
  //  -> "page2-cand0"

  command.Clear();
  ASSERT_TRUE(session->Convert(&command));
  EXPECT_PREEDIT("page0-cand0", command);

  command.Clear();
  command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
  command.mutable_input()->mutable_command()->set_type(
      commands::SessionCommand::CONVERT_NEXT_PAGE);
  ASSERT_TRUE(session->SendCommand(&command));
  EXPECT_PREEDIT("page1-cand0", command);

  command.Clear();
  command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
  command.mutable_input()->mutable_command()->set_type(
      commands::SessionCommand::CONVERT_PREV_PAGE);
  ASSERT_TRUE(session->SendCommand(&command));
  EXPECT_PREEDIT("page0-cand0", command);

  command.Clear();
  command.mutable_input()->set_type(commands::Input::SEND_COMMAND);
  command.mutable_input()->mutable_command()->set_type(
      commands::SessionCommand::CONVERT_PREV_PAGE);
  ASSERT_TRUE(session->SendCommand(&command));
  EXPECT_PREEDIT("page2-cand0", command);
}

TEST_F(SessionTest, NeedlessClearUndoContext) {
  // This is a unittest against http://b/3423910.

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);
  commands::Command command;

  {  // Conversion -> Send Shift -> Undo
    Segments segments;
    InsertCharacterChars("aiueo", session.get(), &command);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    SetAiueo(&segments);
    FillT13Ns(request, &segments);

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);

    SendKey("Shift", session.get(), &command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_preedit());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);
  }

  {  // Type "aiueo" -> Convert -> Type "a" -> Escape -> Undo
    Segments segments;
    InsertCharacterChars("aiueo", session.get(), &command);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    SetAiueo(&segments);
    FillT13Ns(request, &segments);

    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);

    SendKey("a", session.get(), &command);
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);
    // "あ"
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

    SendKey("Escape", session.get(), &command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_preedit());

    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);
  }
}

TEST_F(SessionTest, ClearUndoContextAfterDirectInputAfterConversion) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Prepare Numpad
  config::Config config;
  config.set_numpad_character_form(config::Config::NUMPAD_DIRECT_INPUT);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::NUMPAD_DIRECT_INPUT,
            GET_CONFIG(numpad_character_form));
  // Update KeyEventTransformer
  session->ReloadConfig();

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);
  commands::Command command;

  // Cleate segments
  Segments segments;
  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);

  // Convert
  GetConverterMock()->SetStartConversionForRequest(&segments, true);
  command.Clear();
  session->Convert(&command);
  EXPECT_FALSE(command.output().has_result());
  // "あいうえお"
  EXPECT_PREEDIT(kAiueo, command);

  // Direct input
  SendKey("Numpad0", session.get(), &command);
  EXPECT_TRUE(GetComposition(command).empty());
  // "あいうえお0"
  EXPECT_RESULT(string(kAiueo) + "0", command);

  // Undo - Do NOT nothing
  command.Clear();
  session->Undo(&command);
  EXPECT_FALSE(command.output().has_result());
  EXPECT_FALSE(command.output().has_deletion_range());
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, TemporaryInputModeAfterUndo) {
  // This is a unittest against http://b/3423599.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);
  commands::Command command;

  // Shift + Ascii triggers temporary input mode switch.
  SendKey("A", session.get(), &command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  SendKey("Enter", session.get(), &command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());

  // Undo and keep temporary input mode correct
  command.Clear();
  session->Undo(&command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_PREEDIT("A", command);
  SendKey("Enter", session.get(), &command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());

  // Undo and input additional "A" with temporary input mode.
  command.Clear();
  session->Undo(&command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  SendKey("A", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  EXPECT_PREEDIT("AA", command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  // Input additional "a" with original input mode.
  SendKey("a", session.get(), &command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  EXPECT_FALSE(command.output().has_result());
  // "AAあ"
  EXPECT_PREEDIT("AA\xE3\x81\x82", command);

  // Submit and Undo
  SendKey("Enter", session.get(), &command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  command.Clear();
  session->Undo(&command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  EXPECT_FALSE(command.output().has_result());
  // "AAあ"
  EXPECT_PREEDIT("AA\xE3\x81\x82", command);

  // Input additional "Aa"
  SendKey("A", session.get(), &command);
  SendKey("a", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  // "AAあAa"
  EXPECT_PREEDIT("AA" + string(kHiraganaA) + "Aa", command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  // Submit and Undo
  SendKey("Enter", session.get(), &command);
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  command.Clear();
  session->Undo(&command);
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  EXPECT_FALSE(command.output().has_result());
  // "AAあAa"
  EXPECT_PREEDIT("AA" + string(kHiraganaA) + "Aa", command);
}

TEST_F(SessionTest, DCHECKFailureAfterUndo) {
  // This is a unittest against http://b/3437358.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);
  commands::Command command;

  InsertCharacterChars("abe", session.get(), &command);
  command.Clear();
  session->Commit(&command);
  command.Clear();
  session->Undo(&command);
  EXPECT_FALSE(command.output().has_result());
  // "あべ"
  EXPECT_PREEDIT("\xE3\x81\x82\xE3\x81\xB9", command);

  InsertCharacterChars("s", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  // "あべｓ"
  EXPECT_PREEDIT("\xE3\x81\x82\xE3\x81\xB9\xEF\xBD\x93", command);

  InsertCharacterChars("h", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  // "あべｓｈ"
  EXPECT_PREEDIT("\xE3\x81\x82\xE3\x81\xB9\xEF\xBD\x93\xEF\xBD\x88", command);

  InsertCharacterChars("i", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  // "あべし"
  EXPECT_PREEDIT("\xE3\x81\x82\xE3\x81\xB9\xE3\x81\x97", command);
}

TEST_F(SessionTest, ConvertToFullOrHalfAlphanumericAfterUndo) {
  // This is a unittest against http://b/3423592.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  Segments segments;
  SetAiueo(&segments);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);

  {  // ConvertToHalfASCII
    commands::Command command;
    InsertCharacterChars("aiueo", session.get(), &command);

    SendKey("Enter", session.get(), &command);
    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_EQ(kAiueo, GetComposition(command));

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->ConvertToHalfASCII(&command);
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_preedit());
    EXPECT_EQ("aiueo", GetComposition(command));
  }

  {  // ConvertToFullASCII
    commands::Command command;
    InsertCharacterChars("aiueo", session.get(), &command);

    SendKey("Enter", session.get(), &command);
    command.Clear();
    session->Undo(&command);
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_EQ(kAiueo, GetComposition(command));

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->ConvertToFullASCII(&command);
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_preedit());
    // "ａｉｕｅｏ"
    EXPECT_EQ("\xEF\xBD\x81\xEF\xBD\x89\xEF\xBD\x95\xEF\xBD\x85\xEF\xBD\x8F",
              GetComposition(command));
  }
}

TEST_F(SessionTest, ComposeVoicedSoundMarkAfterUndo_Issue5369632) {
  // This is a unittest against http://b/5369632.
  config::Config config;
  config.set_preedit_method(config::Config::KANA);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::KANA, GET_CONFIG(preedit_method));

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  commands::Command command;

  // "ち"
  InsertCharacterCodeAndString('a', "\xE3\x81\xA1", session.get(), &command);
  // "ち"
  EXPECT_EQ("\xE3\x81\xA1", GetComposition(command));

  SendKey("Enter", session.get(), &command);
  command.Clear();
  session->Undo(&command);

  EXPECT_FALSE(command.output().has_result());
  ASSERT_TRUE(command.output().has_preedit());
  // "ち"
  EXPECT_EQ("\xE3\x81\xA1", GetComposition(command));

  // "゛"
  InsertCharacterCodeAndString('@', "\xE3\x82\x9B", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
  ASSERT_TRUE(command.output().has_preedit());
  // "ぢ"
  EXPECT_EQ("\xE3\x81\xA2", GetComposition(command));
}

TEST_F(SessionTest, SpaceOnAlphanumeric) {
  commands::Request request;
  commands::Command command;

  {
    request.set_space_on_alphanumeric(commands::Request::COMMIT);

    Session session(engine_.get());
    InitSessionToPrecomposition(&session, request);

    SendKey("A", &session, &command);
    EXPECT_EQ("A", GetComposition(command));

    SendKey("Space", &session, &command);
    EXPECT_RESULT("A ", command);
  }

  {
    request.set_space_on_alphanumeric(
        commands::Request::SPACE_OR_CONVERT_COMMITING_COMPOSITION);

    Session session(engine_.get());
    InitSessionToPrecomposition(&session, request);

    SendKey("A", &session, &command);
    EXPECT_EQ("A", GetComposition(command));

    SendKey("Space", &session, &command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("A ", GetComposition(command));

    SendKey("a", &session, &command);
    EXPECT_RESULT("A ", command);
    // "あ"
    EXPECT_EQ(kHiraganaA, GetComposition(command));
  }

  {
    request.set_space_on_alphanumeric(
        commands::Request::SPACE_OR_CONVERT_KEEPING_COMPOSITION);

    Session session(engine_.get());
    InitSessionToPrecomposition(&session, request);

    SendKey("A", &session, &command);
    EXPECT_EQ("A", GetComposition(command));

    SendKey("Space", &session, &command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("A ", GetComposition(command));

    SendKey("a", &session, &command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("A a", GetComposition(command));
  }
}

TEST_F(SessionTest, Issue1805239) {
  // This is a unittest against http://b/1805239.
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("watasinonamae", session.get(), &command);

  segment = segments.add_segment();
  // "わたしの"
  segment->set_key("\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae");
  candidate = segment->add_candidate();
  // "私の"
  candidate->value = "\xe7\xa7\x81\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "渡しの"
  candidate->value = "\xe6\xb8\xa1\xe3\x81\x97\xe3\x81\xae";
  segment = segments.add_segment();
  // "名前"
  segment->set_key("\xe5\x90\x8d\xe5\x89\x8d");
  candidate = segment->add_candidate();
  // "なまえ"
  candidate->value = "\xe3\x81\xaa\xe3\x81\xbe\xe3\x81\x88";
  candidate = segment->add_candidate();
  // "ナマエ"
  candidate->value = "\xe3\x83\x8a\xe3\x83\x9e\xe3\x82\xa8";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  EXPECT_FALSE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  EXPECT_FALSE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());
}

TEST_F(SessionTest, Issue1816861) {
  // This is a unittest against http://b/1816861
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("kamabokonoinbou", session.get(), &command);
  segment = segments.add_segment();
  // "かまぼこの"
  segment->set_key(
      "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae");
  candidate = segment->add_candidate();
  // "かまぼこの"
  candidate->value
      = "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae";
  candidate = segment->add_candidate();
  // "カマボコの"
  candidate->value
      = "\xe3\x82\xab\xe3\x83\x9e\xe3\x83\x9c\xe3\x82\xb3\xe3\x81\xae";
  segment = segments.add_segment();
  // "いんぼう"
  segment->set_key("\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86");
  candidate = segment->add_candidate();
  // "陰謀"
  candidate->value = "\xe9\x99\xb0\xe8\xac\x80";
  candidate = segment->add_candidate();
  // "印房"
  candidate->value = "\xe5\x8d\xb0\xe6\x88\xbf";

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);
  SendSpecialKey(commands::KeyEvent::BACKSPACE, session.get(), &command);

  segments.Clear();
  segment = segments.add_segment();
  // "いんぼう"
  segment->set_key("\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86");
  candidate = segment->add_candidate();
  // "陰謀"
  candidate->value = "\xe9\x99\xb0\xe8\xac\x80";
  candidate = segment->add_candidate();
  // "陰謀論"
  candidate->value = "\xe9\x99\xb0\xe8\xac\x80\xe8\xab\x96";
  candidate = segment->add_candidate();
  // "陰謀説"
  candidate->value = "\xe9\x99\xb0\xe8\xac\x80\xe8\xaa\xac";

  GetConverterMock()->SetStartPredictionForRequest(&segments, true);

  SendSpecialKey(commands::KeyEvent::TAB, session.get(), &command);
}

TEST_F(SessionTest, T13NWithResegmentation) {
  // This is a unittest against http://b/3272827
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("kamabokonoinbou", session.get(), &command);

  {
    Segments segments;
    Segment *segment;
    segment = segments.add_segment();
    // "かまぼこの"
    segment->set_key(
        "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae");
    candidate = segment->add_candidate();
    // "かまぼこの"
    candidate->value
        = "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae";
    candidate = segment->add_candidate();
    // "カマボコの"
    candidate->value
        = "\xe3\x82\xab\xe3\x83\x9e\xe3\x83\x9c\xe3\x82\xb3\xe3\x81\xae";

    segment = segments.add_segment();
    // "いんぼう"
    segment->set_key("\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86");
    candidate = segment->add_candidate();
    // "陰謀"
    candidate->value = "\xe9\x99\xb0\xe8\xac\x80";
    candidate = segment->add_candidate();
    // "印房"
    candidate->value = "\xe5\x8d\xb0\xe6\x88\xbf";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }
  {
    Segments segments;
    Segment *segment;
    segment = segments.add_segment();
    // "かまぼこの"
    segment->set_key(
        "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae");
    candidate = segment->add_candidate();
    // "かまぼこの"
    candidate->value
        = "\xe3\x81\x8b\xe3\x81\xbe\xe3\x81\xbc\xe3\x81\x93\xe3\x81\xae";
    candidate = segment->add_candidate();
    // "カマボコの"
    candidate->value
        = "\xe3\x82\xab\xe3\x83\x9e\xe3\x83\x9c\xe3\x82\xb3\xe3\x81\xae";

    segment = segments.add_segment();
    // "いんぼ"
    segment->set_key("\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc");
    candidate = segment->add_candidate();
    // "いんぼ"
    candidate->value = "\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc";
    candidate = segment->add_candidate();
    // "インボ"
    candidate->value = "\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x9c";

    segment = segments.add_segment();
    // "う"
    segment->set_key("\xe3\x81\x86");
    candidate = segment->add_candidate();
    // "ウ"
    candidate->value = "\xe3\x82\xa6";
    candidate = segment->add_candidate();
    // "卯"
    candidate->value = "\xe5\x8d\xaf";

    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetResizeSegment1(&segments, true);
  }

  // Start conversion
  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  // Select second segment
  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  // Shrink segment
  SendKey("Shift left", session.get(), &command);
  // Convert to T13N (Half katakana)
  SendKey("F8", session.get(), &command);

  // "ｲﾝﾎﾞ"
  EXPECT_EQ("\xef\xbd\xb2\xef\xbe\x9d\xef\xbe\x8e\xef\xbe\x9e",
            command.output().preedit().segment(1).value());
}

TEST_F(SessionTest, Shortcut) {
  const config::Config::SelectionShortcut kDataShortcut[] = {
    config::Config::NO_SHORTCUT,
    config::Config::SHORTCUT_123456789,
    config::Config::SHORTCUT_ASDFGHJKL,
  };
  const string kDataExpected[][2] = {
    {"", ""},
    {"1", "2"},
    {"a", "s"},
  };
  for (size_t i = 0; i < arraysize(kDataShortcut); ++i) {
    config::Config::SelectionShortcut shortcut = kDataShortcut[i];
    const string *expected = kDataExpected[i];

    config::Config config;
    config.set_selection_shortcut(shortcut);
    config::ConfigHandler::SetConfig(config);
    ASSERT_EQ(shortcut, GET_CONFIG(selection_shortcut));

    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    Segments segments;
    SetAiueo(&segments);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    commands::Command command;
    InsertCharacterChars("aiueo", session.get(), &command);

    command.Clear();
    session->Convert(&command);

    command.Clear();
    // Convert next
    SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
    ASSERT_TRUE(command.output().has_candidates());
    const commands::Candidates &candidates = command.output().candidates();
    EXPECT_EQ(expected[0], candidates.candidate(0).annotation().shortcut());
    EXPECT_EQ(expected[1], candidates.candidate(1).annotation().shortcut());
  }
}

TEST_F(SessionTest, ShortcutWithCapsLock_Issue5655743) {
  config::Config config;
  config.set_selection_shortcut(config::Config::SHORTCUT_ASDFGHJKL);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::SHORTCUT_ASDFGHJKL,
            GET_CONFIG(selection_shortcut));

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  Segments segments;
  SetAiueo(&segments);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);

  command.Clear();
  session->Convert(&command);

  command.Clear();
  // Convert next
  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());

  const commands::Candidates &candidates = command.output().candidates();
  EXPECT_EQ("a", candidates.candidate(0).annotation().shortcut());
  EXPECT_EQ("s", candidates.candidate(1).annotation().shortcut());

  // Select the second candidate by 's' key when the CapsLock is enabled.
  // Note that "CAPS S" means that 's' key is pressed w/o shift key.
  // See the description in command.proto.
  EXPECT_TRUE(SendKey("CAPS S", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // "アイウエオ"
  EXPECT_EQ("\xE3\x82\xA2\xE3\x82\xA4\xE3\x82\xA6\xE3\x82\xA8\xE3\x82\xAA",
            GetComposition(command));
}

TEST_F(SessionTest, NumpadKey) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  config::Config config;
  config.set_numpad_character_form(config::Config::NUMPAD_DIRECT_INPUT);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::NUMPAD_DIRECT_INPUT,
            GET_CONFIG(numpad_character_form));
  // Update KeyEventTransformer
  session->ReloadConfig();

  // In the Precomposition state, numpad keys should not be consumed.
  EXPECT_TRUE(TestSendKey("Numpad1", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(SendKey("Numpad1", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());

  EXPECT_TRUE(TestSendKey("Add", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(SendKey("Add", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());

  EXPECT_TRUE(TestSendKey("Equals", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(SendKey("Equals", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());

  EXPECT_TRUE(TestSendKey("Separator", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(SendKey("Separator", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());

  EXPECT_TRUE(GetComposition(command).empty());

  config.set_numpad_character_form(config::Config::NUMPAD_HALF_WIDTH);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::NUMPAD_HALF_WIDTH,
            GET_CONFIG(numpad_character_form));
  // Update KeyEventTransformer
  session->ReloadConfig();

  // In the Precomposition state, numpad keys should not be consumed.
  EXPECT_TRUE(TestSendKey("Numpad1", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_TRUE(SendKey("Numpad1", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ("1", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Add", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_TRUE(SendKey("Add", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ("1+", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Equals", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_TRUE(SendKey("Equals", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ("1+=", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Separator", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_TRUE(SendKey("Separator", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  EXPECT_TRUE(GetComposition(command).empty());

  // "0" should be treated as full-width "０".
  EXPECT_TRUE(TestSendKey("0", session.get(), &command));
  EXPECT_TRUE(SendKey("0", session.get(), &command));

  // "０"
  EXPECT_SINGLE_SEGMENT_AND_KEY("\xEF\xBC\x90", "\xEF\xBC\x90", command);

  // In the Composition state, DIVIDE on the pre-edit should be treated as "/".
  EXPECT_TRUE(TestSendKey("Divide", session.get(), &command));
  EXPECT_TRUE(SendKey("Divide", session.get(), &command));

  // "０/"
  EXPECT_SINGLE_SEGMENT_AND_KEY(
      "\xEF\xBC\x90\x2F", "\xEF\xBC\x90\x2F", command);

  // In the Composition state, "Numpad0" should be treated as half-width "0".
  EXPECT_TRUE(SendKey("Numpad0", session.get(), &command));

  // "０/0"
  EXPECT_SINGLE_SEGMENT_AND_KEY(
      "\xEF\xBC\x90\x2F\x30", "\xEF\xBC\x90\x2F\x30", command);

  // Separator should be treated as Enter.
  EXPECT_TRUE(TestSendKey("Separator", session.get(), &command));
  EXPECT_TRUE(SendKey("Separator", session.get(), &command));

  EXPECT_FALSE(command.output().has_preedit());
  // "０/0"
  EXPECT_RESULT("\xEF\xBC\x90\x2F\x30", command);

  // http://b/2097087
  EXPECT_TRUE(SendKey("0", session.get(), &command));

  // "０"
  EXPECT_SINGLE_SEGMENT_AND_KEY("\xEF\xBC\x90", "\xEF\xBC\x90", command);

  EXPECT_TRUE(SendKey("Divide", session.get(), &command));
  // "０/"
  EXPECT_SINGLE_SEGMENT_AND_KEY(
      "\xEF\xBC\x90\x2F", "\xEF\xBC\x90\x2F", command);

  EXPECT_TRUE(SendKey("Divide", session.get(), &command));
  // "０//"
  EXPECT_SINGLE_SEGMENT_AND_KEY(
      "\xEF\xBC\x90\x2F\x2F", "\xEF\xBC\x90\x2F\x2F", command);

  EXPECT_TRUE(SendKey("Subtract", session.get(), &command));
  EXPECT_TRUE(SendKey("Subtract", session.get(), &command));
  EXPECT_TRUE(SendKey("Decimal", session.get(), &command));
  EXPECT_TRUE(SendKey("Decimal", session.get(), &command));
  // "０//--.."
  EXPECT_SINGLE_SEGMENT_AND_KEY(
      "\xEF\xBC\x90\x2F\x2F\x2D\x2D\x2E\x2E",
      "\xEF\xBC\x90\x2F\x2F\x2D\x2D\x2E\x2E", command);
}

TEST_F(SessionTest, KanaSymbols) {
  config::Config config;
  config.set_punctuation_method(config::Config::COMMA_PERIOD);
  config.set_symbol_method(config::Config::CORNER_BRACKET_SLASH);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::COMMA_PERIOD, GET_CONFIG(punctuation_method));
  ASSERT_EQ(config::Config::CORNER_BRACKET_SLASH, GET_CONFIG(symbol_method));

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  {
    commands::Command command;
    SetSendKeyCommand("<", &command);
    // "、"
    command.mutable_input()->mutable_key()->set_key_string("\xe3\x80\x81");
    EXPECT_TRUE(session->SendKey(&command));
    // "，"
    EXPECT_EQ(static_cast<uint32>(','), command.input().key().key_code());
    EXPECT_EQ("\xef\xbc\x8c", command.input().key().key_string());
    EXPECT_EQ("\xef\xbc\x8c", command.output().preedit().segment(0).value());
  }
  {
    commands::Command command;
    session->EditCancel(&command);
  }
  {
    commands::Command command;
    SetSendKeyCommand("?", &command);
    // "・"
    command.mutable_input()->mutable_key()->set_key_string("\xe3\x83\xbb");
    EXPECT_TRUE(session->SendKey(&command));
    // "／"
    EXPECT_EQ(static_cast<uint32>('/'), command.input().key().key_code());
    EXPECT_EQ("\xef\xbc\x8f", command.input().key().key_string());
    EXPECT_EQ("\xef\xbc\x8f", command.output().preedit().segment(0).value());
  }
}

TEST_F(SessionTest, InsertCharacterWithShiftKey) {
  {  // Basic behavior
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(SendKey("A", session.get(), &command));  // "あA"
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あAa"
    // Shift reverts the input mode to Hiragana.
    EXPECT_TRUE(SendKey("Shift", session.get(), &command));
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あAaあ"
    // Shift does nothing because the input mode has already been reverted.
    EXPECT_TRUE(SendKey("Shift", session.get(), &command));
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あAaああ"
    // "あAaああ"
    EXPECT_EQ("\xE3\x81\x82\x41\x61\xE3\x81\x82\xE3\x81\x82",
              GetComposition(command));
  }

  {  // Revert back to the previous input mode.
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    session->InputModeFullKatakana(&command);
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(SendKey("A", session.get(), &command));  // "アA"
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "アAa"
    // Shift reverts the input mode to Hiragana.
    EXPECT_TRUE(SendKey("Shift", session.get(), &command));
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "アAaア"
    // Shift does nothing because the input mode has already been reverted.
    EXPECT_TRUE(SendKey("Shift", session.get(), &command));
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "アAaアア"
    // "アAaアア"
    EXPECT_EQ("\xE3\x82\xA2\x41\x61\xE3\x82\xA2\xE3\x82\xA2",
              GetComposition(command));
  }
}

TEST_F(SessionTest, ExitTemporaryAlphanumModeAfterCommitingSugesstion) {
  // This is a unittest against http://b/2977131.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("N", session.get(), &command));
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    Segments segments;
    Segment *segment = segments.add_segment();
    segment->set_key("NFL");
    segment->add_candidate()->value = "NFL";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    EXPECT_TRUE(session->Convert(&command));
    EXPECT_FALSE(command.output().has_candidates());
    EXPECT_FALSE(command.output().candidates().has_focused_index());
    EXPECT_EQ(0, command.output().candidates().focused_index());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_FALSE(command.output().has_candidates());
    EXPECT_RESULT("NFL", command);
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("N", session.get(), &command));
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    Segments segments;
    Segment *segment = segments.add_segment();
    segment->set_key("NFL");
    segment->add_candidate()->value = "NFL";
    GetConverterMock()->SetStartPredictionForRequest(&segments, true);

    EXPECT_TRUE(session->PredictAndConvert(&command));
    ASSERT_TRUE(command.output().has_candidates());
    EXPECT_TRUE(command.output().candidates().has_focused_index());
    EXPECT_EQ(0, command.output().candidates().focused_index());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_FALSE(command.output().has_candidates());
    EXPECT_RESULT("NFL", command);

    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("N", session.get(), &command));
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    Segments segments;
    Segment *segment = segments.add_segment();
    segment->set_key("NFL");
    segment->add_candidate()->value = "NFL";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    EXPECT_TRUE(session->ConvertToHalfASCII(&command));
    EXPECT_FALSE(command.output().has_candidates());
    EXPECT_FALSE(command.output().candidates().has_focused_index());
    EXPECT_EQ(0, command.output().candidates().focused_index());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_FALSE(command.output().has_candidates());
    EXPECT_RESULT("NFL", command);
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
  }
}

TEST_F(SessionTest, StatusOutput) {
  {  // Basic behavior
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あ"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    // command.output().mode() is going to be obsolete.
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("A", session.get(), &command));  // "あA"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あAa"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    // Shift reverts the input mode to Hiragana.
    EXPECT_TRUE(SendKey("Shift", session.get(), &command));
    EXPECT_TRUE(SendKey("a", session.get(), &command));  // "あAaあ"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("A", session.get(), &command));  // "あAaあA"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as HIRAGANA
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());

    // When the IME is deactivated, the temporary composition mode is reset.
    EXPECT_TRUE(SendKey("OFF", session.get(), &command));  // "あAaあA"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
    // command.output().mode() always returns DIRECT when IME is
    // deactivated.  This is the reason why command.output().mode() is
    // going to be obsolete.
    EXPECT_EQ(commands::DIRECT, command.output().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().comeback_mode());
  }

  {  // Katakana mode + Shift key
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    session->InputModeFullKatakana(&command);
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
    EXPECT_EQ(commands::FULL_KATAKANA,
              command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());  // obsolete
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
    EXPECT_EQ(commands::FULL_KATAKANA,
              command.output().status().comeback_mode());

    EXPECT_TRUE(SendKey("A", session.get(), &command));  // "アA"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());  // obsolete
    EXPECT_EQ(commands::HALF_ASCII, command.output().status().mode());
    // Global mode should be kept as FULL_KATAKANA
    EXPECT_EQ(commands::FULL_KATAKANA,
              command.output().status().comeback_mode());

    // When the IME is deactivated, the temporary composition mode is reset.
    EXPECT_TRUE(SendKey("OFF", session.get(), &command));  // "アA"
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
    // command.output().mode() always returns DIRECT when IME is
    // deactivated.  This is the reason why command.output().mode() is
    // going to be obsolete.
    EXPECT_EQ(commands::DIRECT, command.output().mode());
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
    EXPECT_EQ(commands::FULL_KATAKANA,
              command.output().status().comeback_mode());
  }
}

TEST_F(SessionTest, Suggest) {
  Segments segments_m;
  {
    segments_m.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_m.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_moz;
  {
    segments_moz.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_moz.add_segment();
    segment->set_key("MOZ");
    segment->add_candidate()->value = "MOZUKU";
  }

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  SendKey("M", session.get(), &command);

  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // moz|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_moz, true);
  SendKey("Z", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(1, command.output().candidates().candidate_size());
  EXPECT_EQ("MOZUKU", command.output().candidates().candidate(0).value());

  // mo|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("Backspace", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // m|o
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorLeft(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // mo|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorToEnd(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // |mo
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorToBeginning(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // m|o
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorRight(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  // m|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);
  command.Clear();
  EXPECT_TRUE(session->Delete(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  Segments segments_m_conv;
  {
    segments_m_conv.set_request_type(Segments::CONVERSION);
    Segment *segment;
    segment = segments_m_conv.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "M";
    segment->add_candidate()->value = "m";
  }
  ConversionRequest request_m_conv;
  SetComposer(session.get(), &request_m_conv);
  FillT13Ns(request_m_conv, &segments_m_conv);
  GetConverterMock()->SetStartConversionForRequest(&segments_m_conv, true);
  command.Clear();
  EXPECT_TRUE(session->Convert(&command));

  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);
  command.Clear();
  EXPECT_TRUE(session->ConvertCancel(&command));
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());
}

TEST_F(SessionTest, ExpandSuggestion) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // Prepare suggestion candidates.
  Segments segments_m;
  {
    segments_m.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_m.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }
  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);

  SendKey("M", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());

  // Prepare expanded suggestion candidates.
  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOZUKU";
    segment->add_candidate()->value = "MOZUKUSU";
  }
  GetConverterMock()->SetStartPredictionForRequest(&segments_mo, true);

  command.Clear();
  EXPECT_TRUE(session->ExpandSuggestion(&command));
  ASSERT_TRUE(command.output().has_candidates());
  // 3 == MOCHA, MOZUKU and MOZUKUSU (duplicate MOZUKU is not counted).
  EXPECT_EQ(3, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());
}

TEST_F(SessionTest, ExpandSuggestionDirectMode) {
  // On direct mode, ExpandSuggestion() should do nothing.
  scoped_ptr<Session> session(new Session(engine_.get()));
  commands::Command command;

  session->IMEOff(&command);
  EXPECT_TRUE(session->ExpandSuggestion(&command));
  ASSERT_FALSE(command.output().has_candidates());

  // This test expects that ConverterInterface.StartPrediction() is not called
  // so SetStartPredictionForRequest() is not called.
}

TEST_F(SessionTest, ExpandSuggestionConversionMode) {
  // On conversion mode, ExpandSuggestion() should do nothing.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  InsertCharacterChars("aiueo", session.get(), &command);
  Segments segments;
  ConversionRequest request;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  command.Clear();
  session->ConvertNext(&command);

  EXPECT_TRUE(session->ExpandSuggestion(&command));

  // This test expects that ConverterInterface.StartPrediction() is not called
  // so SetStartPredictionForRequest() is not called.
}

TEST_F(SessionTest, CommitCandidate_TypingCorrection) {
  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(Request::QWERTY_MOBILE_TO_HIRAGANA);

  Segments segments_jueri;
  segments_jueri.set_request_type(Segments::PARTIAL_SUGGESTION);
  Segment *segment;
  segment = segments_jueri.add_segment();
  // "じゅえり"
  const char kJueri[] = "\xE3\x81\x98\xE3\x82\x85\xE3\x81\x88\xE3\x82\x8A";
  segment->set_key(kJueri);
  Segment::Candidate *candidate = segment->add_candidate();
  candidate->key = "\xE3\x81\x8F\xE3\x81\x88\xE3\x82\x8A";  // "くえり"
  candidate->content_key = candidate->key;
  candidate->value = "\xE3\x82\xAF\xE3\x82\xA8\xE3\x83\xAA";  // "クエリ"
  candidate->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
  candidate->consumed_key_size = Util::CharsLen(kJueri);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get(), request);

  commands::Command command;
  GetConverterMock()->SetStartSuggestionForRequest(&segments_jueri, true);
  InsertCharacterChars("jueri", session.get(), &command);

  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(1, command.output().preedit().segment_size());
  EXPECT_EQ(kJueri,
            command.output().preedit().segment(0).key());
  EXPECT_EQ(1, command.output().candidates().candidate_size());
  EXPECT_EQ("\xE3\x82\xAF\xE3\x82\xA8\xE3\x83\xAA",  // "クエリ"
            command.output().candidates().candidate(0).value());

  // commit partial suggestion
  Segments empty_segments;
  GetConverterMock()->SetFinishConversion(&empty_segments, true);
  SetSendCommandCommand(commands::SessionCommand::SUBMIT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(0);
  GetConverterMock()->SetStartSuggestionForRequest(&segments_jueri, true);
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  // "クエリ", "くえり"
  EXPECT_RESULT_AND_KEY(
      "\xE3\x82\xAF\xE3\x82\xA8\xE3\x83\xAA",
      "\xE3\x81\x8F\xE3\x81\x88\xE3\x82\x8A", command);
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, MobilePartialSuggestion) {
  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(
      commands::Request::QWERTY_MOBILE_TO_HIRAGANA);

  Segments segments_wata;
  {
    segments_wata.set_request_type(Segments::PARTIAL_SUGGESTION);
    Segment *segment;
    segment = segments_wata.add_segment();
    // "わた"
    const char kWata[] = "\xe3\x82\x8f\xe3\x81\x9f";
    segment->set_key(kWata);
    Segment::Candidate *cand1 = AddCandidate(kWata,
                                     "\xe7\xb6\xbf", segment);  // "綿"
    cand1->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
    cand1->consumed_key_size = Util::CharsLen(kWata);
    Segment::Candidate *cand2 = AddCandidate(kWata, kWata, segment);
    cand2->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
    cand2->consumed_key_size = Util::CharsLen(kWata);
  }

  Segments segments_watashino;
  {
    segments_watashino.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_watashino.add_segment();
    // "わたしの"
    const char kWatashino[] =
        "\xe3\x82\x8f\xe3\x81\x9f\xe3\x81\x97\xe3\x81\xae";
    segment->set_key(kWatashino);
    Segment::Candidate *cand1 = segment->add_candidate();
    cand1->value = "\xe7\xa7\x81\xe3\x81\xae";  //  "私の";
    cand1->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
    cand1->consumed_key_size = Util::CharsLen(kWatashino);
    Segment::Candidate *cand2 = segment->add_candidate();
    cand2->value = kWatashino;
    cand2->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
    cand2->consumed_key_size = Util::CharsLen(kWatashino);
  }

  Segments segments_shino;
  {
    segments_shino.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_shino.add_segment();
    // "しの"
    const char kShino[] = "\xe3\x81\x97\xe3\x81\xae";
    segment->set_key(kShino);
    Segment::Candidate *candidate;
    candidate = AddCandidate(
        "\xe3\x81\x97\xe3\x81\xae\xe3\x81\xbf\xe3\x82\x84",  // "しのみや"
        "\xe5\x9b\x9b\xe3\x83\x8e\xe5\xae\xae", segment);  // "四ノ宮"
    candidate->content_key = segment->key();
    candidate->attributes = Segment::Candidate::PARTIALLY_KEY_CONSUMED;
    candidate->consumed_key_size = Util::CharsLen(kShino);
    candidate = AddCandidate(kShino, "shino", segment);
  }

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get(), request);

  commands::Command command;
  GetConverterMock()->SetStartSuggestionForRequest(&segments_watashino, true);
  InsertCharacterChars("watashino", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  // "私の"
  EXPECT_EQ("\xe7\xa7\x81\xe3\x81\xae",
            command.output().candidates().candidate(0).value());

  // partial suggestion for "わた|しの"
  GetConverterMock()->SetStartPartialSuggestion(&segments_wata, false);
  GetConverterMock()->SetStartPartialSuggestionForRequest(&segments_wata, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorLeft(&command));
  command.Clear();
  EXPECT_TRUE(session->MoveCursorLeft(&command));
  // partial suggestion candidates
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  // "綿"
  EXPECT_EQ("\xe7\xb6\xbf", command.output().candidates().candidate(0).value());

  // commit partial suggestion
  SetSendCommandCommand(commands::SessionCommand::SUBMIT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(0);
  GetConverterMock()->SetStartSuggestionForRequest(&segments_shino, true);
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  // "綿", "わた"
  EXPECT_RESULT_AND_KEY("\xe7\xb6\xbf", "\xe3\x82\x8f\xe3\x81\x9f", command);

  // remaining text in preedit
  EXPECT_EQ(2, command.output().preedit().cursor());
  // "しの"
  EXPECT_SINGLE_SEGMENT("\xe3\x81\x97\xe3\x81\xae", command);

  // Suggestion for new text fills the candidates.
  EXPECT_TRUE(command.output().has_candidates());
  // "四ノ宮"
  EXPECT_EQ("\xe5\x9b\x9b\xe3\x83\x8e\xe5\xae\xae",
      command.output().candidates().candidate(0).value());
}

TEST_F(SessionTest, ToggleAlphanumericMode) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  {
    InsertCharacterChars("a", session.get(), &command);
    // "あ"
    EXPECT_EQ(kHiraganaA, GetComposition(command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    command.Clear();
    session->ToggleAlphanumericMode(&command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
    InsertCharacterChars("a", session.get(), &command);
    // "あa"
    EXPECT_EQ("\xE3\x81\x82\x61", GetComposition(command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    command.Clear();
    session->ToggleAlphanumericMode(&command);
    InsertCharacterChars("a", session.get(), &command);
    // "あaあ"
    EXPECT_EQ("\xE3\x81\x82\x61\xE3\x81\x82", GetComposition(command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }

  {
    // ToggleAlphanumericMode on Precomposition mode should work.
    command.Clear();
    session->EditCancel(&command);
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    session->ToggleAlphanumericMode(&command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
    InsertCharacterChars("a", session.get(), &command);
    EXPECT_EQ("a", GetComposition(command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  }

  {
    // A single "n" on Hiragana mode should not converted to "ん" for
    // the compatibility with MS-IME.
    command.Clear();
    session->EditCancel(&command);
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    session->ToggleAlphanumericMode(&command);
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
    InsertCharacterChars("n", session.get(), &command);  // on Hiragana mode
    // "ｎ"
    EXPECT_EQ("\xEF\xBD\x8E", GetComposition(command));

    command.Clear();
    session->ToggleAlphanumericMode(&command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
    InsertCharacterChars("a", session.get(), &command);  // on Half ascii mode.
    // "ｎa"
    EXPECT_EQ("\xEF\xBD\x8E\x61", GetComposition(command));
  }

  {
    // ToggleAlphanumericMode should work even when it is called in
    // the conversion state.
    command.Clear();
    session->EditCancel(&command);
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    session->InputModeHiragana(&command);
    InsertCharacterChars("a", session.get(), &command);  // on Hiragana mode
    // "あ"
    EXPECT_EQ(kHiraganaA, GetComposition(command));

    Segments segments;
    SetAiueo(&segments);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    session->Convert(&command);

    // "あいうえお"
    EXPECT_EQ(kAiueo, GetComposition(command));

    command.Clear();
    session->ToggleAlphanumericMode(&command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    command.Clear();
    session->Commit(&command);

    InsertCharacterChars("a", session.get(), &command);  // on Half ascii mode.
    EXPECT_EQ("a", GetComposition(command));
  }
}

TEST_F(SessionTest, InsertSpace) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  commands::KeyEvent space_key;
  space_key.set_special_key(commands::KeyEvent::SPACE);

  // Default should be FULL_WIDTH.
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpace(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  // "　" (full-width space)
  EXPECT_RESULT(kFullWidthSpace, command);

  // Change the setting to HALF_WIDTH.
  config::Config config;
  config.set_space_character_form(config::Config::FUNDAMENTAL_HALF_WIDTH);
  config::ConfigHandler::SetConfig(config);
  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpace(&command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  // Change the setting to FULL_WIDTH.
  config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
  config::ConfigHandler::SetConfig(config);
  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpace(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  // "　" (full-width space)
  EXPECT_RESULT(kFullWidthSpace, command);
}

TEST_F(SessionTest, InsertSpaceToggled) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  commands::KeyEvent space_key;
  space_key.set_special_key(commands::KeyEvent::SPACE);

  // Default should be FULL_WIDTH.  So the toggled space should be
  // half-width.
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceToggled(&command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  // Change the setting to HALF_WIDTH.
  config::Config config;
  config.set_space_character_form(config::Config::FUNDAMENTAL_HALF_WIDTH);
  config::ConfigHandler::SetConfig(config);
  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceToggled(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  // "　" (full-width space)
  EXPECT_RESULT(kFullWidthSpace, command);

  // Change the setting to FULL_WIDTH.
  config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
  config::ConfigHandler::SetConfig(config);
  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceToggled(&command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, InsertSpaceHalfWidth) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  commands::KeyEvent space_key;
  space_key.set_special_key(commands::KeyEvent::SPACE);

  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceHalfWidth(&command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  EXPECT_TRUE(SendKey("a", session.get(), &command));
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  command.Clear();
  EXPECT_TRUE(session->InsertSpaceHalfWidth(&command));
  // "あ "
  EXPECT_EQ("\xE3\x81\x82\x20", GetComposition(command));

  {  // Convert "あ " with dummy conversions.
    Segments segments;
    // "亜 "
    segments.add_segment()->add_candidate()->value = "\xE4\xBA\x9C\x20";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    EXPECT_TRUE(session->Convert(&command));
  }

  command.Clear();
  EXPECT_TRUE(session->InsertSpaceHalfWidth(&command));
  // "亜  "
  EXPECT_EQ("\xE4\xBA\x9C  ", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
}

TEST_F(SessionTest, InsertSpaceFullWidth) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  commands::KeyEvent space_key;
  space_key.set_special_key(commands::KeyEvent::SPACE);

  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceFullWidth(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_RESULT(kFullWidthSpace, command);

  EXPECT_TRUE(SendKey("a", session.get(), &command));
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceFullWidth(&command));
  // "あ　" (full-width space)
  EXPECT_EQ("\xE3\x81\x82\xE3\x80\x80", GetComposition(command));

  {  // Convert "あ　" with dummy conversions.
    Segments segments;
    // "亜　"
    segments.add_segment()->add_candidate()->value = "\xE4\xBA\x9C\xE3\x80\x80";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);

    command.Clear();
    EXPECT_TRUE(session->Convert(&command));
  }

  command.Clear();
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceFullWidth(&command));
  // "亜　　"
  EXPECT_EQ("\xE4\xBA\x9C\xE3\x80\x80\xE3\x80\x80",
            command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
}

TEST_F(SessionTest, InsertSpaceWithInputMode) {
  // First, test against http://b/6027559
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\tSpace\tInsertSpace\n"
        "Composition\tSpace\tInsertSpace\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);
    config::ConfigHandler::SetConfig(config);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_FALSE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    // In this case, space key event should not be consumed.
    EXPECT_FALSE(command.output().consumed());
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKey("a", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "あ"
    EXPECT_PREEDIT(kHiraganaA, command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());

    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "あ "
    EXPECT_PREEDIT(string(kHiraganaA) + " ", command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());
  }

  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\tSpace\tInsertAlternateSpace\n"
        "Composition\tSpace\tInsertAlternateSpace\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);
    config::ConfigHandler::SetConfig(config);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "　"
    EXPECT_RESULT(kFullWidthSpace, command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
    EXPECT_EQ(commands::HALF_KATAKANA, command.output().mode());
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKey("a", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "あ"
    EXPECT_PREEDIT(kHiraganaA, command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());

    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_KATAKANA, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "あ　"
    EXPECT_PREEDIT(string(kHiraganaA) + kFullWidthSpace, command);
    EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());
  }

  // Second, the 1st case filed in http://b/2936141
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\tSpace\tInsertSpace\n"
        "Composition\tSpace\tInsertSpace\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);

    config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
    config::ConfigHandler::SetConfig(config);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "　"
    EXPECT_RESULT(kFullWidthSpace, command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session->context().state());
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "a", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "a", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_PREEDIT("a", command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::HALF_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "a　"
    EXPECT_PREEDIT(string("a") + kFullWidthSpace, command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());
  }

  // Finally, the 2nd case filed in http://b/2936141
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\tSpace\tInsertSpace\n"
        "Composition\tSpace\tInsertSpace\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);

    config.set_space_character_form(config::Config::FUNDAMENTAL_HALF_WIDTH);
    config::ConfigHandler::SetConfig(config);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::FULL_ASCII, session.get(), &command));
    EXPECT_FALSE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::FULL_ASCII, session.get(), &command));
    EXPECT_FALSE(command.output().consumed());
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    EXPECT_TRUE(TestSendKeyWithMode(
        "a", commands::FULL_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "a", commands::FULL_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "ａ"
    EXPECT_PREEDIT(kFullWidthSmallA, command);
    EXPECT_EQ(commands::FULL_ASCII, command.output().mode());

    EXPECT_TRUE(TestSendKeyWithMode(
        "Space", commands::FULL_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKeyWithMode(
        "Space", commands::FULL_ASCII, session.get(), &command));
    EXPECT_TRUE(command.output().consumed());
    // "ａ "
    EXPECT_PREEDIT(kFullWidthSmallA + string(" "), command);
    EXPECT_EQ(commands::FULL_ASCII, command.output().mode());
  }
}

TEST_F(SessionTest, InsertSpaceWithCustomKeyBinding) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Precomposition\tSpace\tInsertSpace\n"
      "Precomposition\tShift Space\tInsertSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config.set_space_character_form(config::Config::FUNDAMENTAL_HALF_WIDTH);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // A plain space key event dispatched to InsertHalfSpace should be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  SetUndoContext(session.get());
  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  // A space key event with any modifier key dispatched to InsertHalfSpace
  // should be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // It is OK not to check |TryUndoAndAssertDoNothing| here because this
  // (test) send key event is actually *consumed*.

  EXPECT_TRUE(SendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_RESULT(" ", command);
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
}

TEST_F(SessionTest, InsertAlternateSpaceWithCustomKeyBinding) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Precomposition\tSpace\tInsertAlternateSpace\n"
      "Precomposition\tShift Space\tInsertAlternateSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // A plain space key event dispatched to InsertHalfSpace should be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  SetUndoContext(session.get());
  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  // A space key event with any modifier key dispatched to InsertHalfSpace
  // should be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // It is OK not to check |TryUndoAndAssertDoNothing| here because this
  // (test) send key event is actually *consumed*.

  EXPECT_TRUE(SendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_RESULT(" ", command);
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
}

TEST_F(SessionTest, InsertSpaceHalfWidthWithCustomKeyBinding) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Precomposition\tSpace\tInsertHalfSpace\n"
      "Precomposition\tShift Space\tInsertHalfSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // A plain space key event assigned to InsertHalfSpace should be echoed back.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  SetUndoContext(session.get());
  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());  // should not be consumed.
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  // A space key event with any modifier key assigned to InsertHalfSpace should
  // be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // It is OK not to check |TryUndoAndAssertDoNothing| here because this
  // (test) send key event is actually *consumed*.

  EXPECT_TRUE(SendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_RESULT(" ", command);
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
}

TEST_F(SessionTest, InsertSpaceFullWidthWithCustomKeyBinding) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Precomposition\tSpace\tInsertFullSpace\n"
      "Precomposition\tShift Space\tInsertFullSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToDirect(session.get());

  commands::Command command;

  // A plain space key event assigned to InsertFullSpace should be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // It is OK not to check |TryUndoAndAssertDoNothing| here because this
  // (test) send key event is actually *consumed*.

  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  // "　" (full-width space)
  EXPECT_RESULT(kFullWidthSpace, command);
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));

  // A space key event with any modifier key assigned to InsertFullSpace should
  // be consumed.
  SetUndoContext(session.get());
  EXPECT_TRUE(TestSendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  // It is OK not to check |TryUndoAndAssertDoNothing| here because this
  // (test) send key event is actually *consumed*.

  EXPECT_TRUE(SendKey("Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  // "　" (full-width space)
  EXPECT_RESULT(kFullWidthSpace, command);
  EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
}

TEST_F(SessionTest, InsertSpaceInDirectMode) {
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Direct\tCtrl a\tInsertSpace\n"
      "Direct\tCtrl b\tInsertAlternateSpace\n"
      "Direct\tCtrl c\tInsertHalfSpace\n"
      "Direct\tCtrl d\tInsertFullSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToDirect(session.get());

  commands::Command command;

  // [InsertSpace] should be echoes back in the direct mode.
  EXPECT_TRUE(TestSendKey("Ctrl a", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_TRUE(SendKey("Ctrl a", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  // [InsertAlternateSpace] should be echoes back in the direct mode.
  EXPECT_TRUE(TestSendKey("Ctrl b", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_TRUE(SendKey("Ctrl b", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  // [InsertHalfSpace] should be echoes back in the direct mode.
  EXPECT_TRUE(TestSendKey("Ctrl c", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_TRUE(SendKey("Ctrl c", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());

  // [InsertFullSpace] should be echoes back in the direct mode.
  EXPECT_TRUE(TestSendKey("Ctrl d", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
  EXPECT_TRUE(SendKey("Ctrl d", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, InsertSpaceInCompositionMode) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Composition\tCtrl a\tInsertSpace\n"
      "Composition\tCtrl b\tInsertAlternateSpace\n"
      "Composition\tCtrl c\tInsertHalfSpace\n"
      "Composition\tCtrl d\tInsertFullSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  SendKey("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));
  EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());

  EXPECT_TRUE(TestSendKey("Ctrl a", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  SendKey("Ctrl a", session.get(), &command);
  // "あ　"
  EXPECT_EQ("\xE3\x81\x82\xE3\x80\x80", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Ctrl b", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  SendKey("Ctrl b", session.get(), &command);
  // "あ　 "
  EXPECT_EQ("\xE3\x81\x82\xE3\x80\x80 ", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Ctrl c", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  SendKey("Ctrl c", session.get(), &command);
  // "あ　  "
  EXPECT_EQ("\xE3\x81\x82\xE3\x80\x80  ", GetComposition(command));

  EXPECT_TRUE(TestSendKey("Ctrl d", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  SendKey("Ctrl d", session.get(), &command);
  // "あ　  　"
  EXPECT_EQ("\xE3\x81\x82\xE3\x80\x80  \xE3\x80\x80", GetComposition(command));
}

TEST_F(SessionTest, InsertSpaceInConversionMode) {
  // This is a unittest against http://b/5872031
  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "Conversion\tCtrl a\tInsertSpace\n"
      "Conversion\tCtrl b\tInsertAlternateSpace\n"
      "Conversion\tCtrl c\tInsertHalfSpace\n"
      "Conversion\tCtrl d\tInsertFullSpace\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));

  {
    InitSessionToConversionWithAiueo(session.get());
    commands::Command command;

    EXPECT_TRUE(TestSendKey("Ctrl a", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("Ctrl a", session.get(), &command));
    EXPECT_TRUE(GetComposition(command).empty());
    ASSERT_TRUE(command.output().has_result());
    // "あいうえお　"
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88"
              "\xE3\x81\x8A\xE3\x80\x80",
              command.output().result().value());
    EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
  }

  {
    InitSessionToConversionWithAiueo(session.get());
    commands::Command command;

    EXPECT_TRUE(TestSendKey("Ctrl b", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("Ctrl b", session.get(), &command));
    EXPECT_TRUE(GetComposition(command).empty());
    ASSERT_TRUE(command.output().has_result());
    // "あいうえお "
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A ",
              command.output().result().value());
    EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
  }

  {
    InitSessionToConversionWithAiueo(session.get());
    commands::Command command;

    EXPECT_TRUE(TestSendKey("Ctrl c", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("Ctrl c", session.get(), &command));
    EXPECT_TRUE(GetComposition(command).empty());
    ASSERT_TRUE(command.output().has_result());
    // "あいうえお "
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A ",
              command.output().result().value());
    EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
  }

  {
    InitSessionToConversionWithAiueo(session.get());
    commands::Command command;

    EXPECT_TRUE(TestSendKey("Ctrl d", session.get(), &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("Ctrl d", session.get(), &command));
    EXPECT_TRUE(GetComposition(command).empty());
    ASSERT_TRUE(command.output().has_result());
    // "あいうえお　"
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88"
              "\xE3\x81\x8A\xE3\x80\x80",
              command.output().result().value());
    EXPECT_TRUE(TryUndoAndAssertDoNothing(session.get()));
  }
}

TEST_F(SessionTest, InsertSpaceFullWidthOnHalfKanaInput) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  EXPECT_TRUE(session->InputModeHalfKatakana(&command));
  EXPECT_EQ(commands::HALF_KATAKANA, command.output().mode());
  InsertCharacterChars("a", session.get(), &command);
  // "ｱ"
  EXPECT_EQ("\xEF\xBD\xB1", GetComposition(command));

  command.Clear();
  commands::KeyEvent space_key;
  space_key.set_special_key(commands::KeyEvent::SPACE);
  command.mutable_input()->mutable_key()->CopyFrom(space_key);
  EXPECT_TRUE(session->InsertSpaceFullWidth(&command));
  // "ｱ　" (full-width space)
  EXPECT_EQ("\xEF\xBD\xB1\xE3\x80\x80", GetComposition(command));
}

TEST_F(SessionTest, IsFullWidthInsertSpace) {
  scoped_ptr<Session> session;
  config::Config config;

  { // When |empty_command| does not have |empty_command.key().input()| field,
    // the current input mode will be used.

    // Default config -- follow to the current mode.
    config.set_space_character_form(config::Config::FUNDAMENTAL_INPUT_MODE);
    config::ConfigHandler::SetConfig(config);
    session.reset(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Input empty_input;

    // Hiragana
    commands::Command command;
    session->InputModeHiragana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Full-Katakana
    command.Clear();
    session->InputModeFullKatakana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Half-Katakana
    command.Clear();
    session->InputModeHalfKatakana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Full-ASCII
    command.Clear();
    session->InputModeFullASCII(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Half-ASCII
    command.Clear();
    session->InputModeHalfASCII(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Direct
    command.Clear();
    session->IMEOff(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));

    // Set config to 'half' -- all mode has to emit half-width space.
    config.set_space_character_form(config::Config::FUNDAMENTAL_HALF_WIDTH);
    config::ConfigHandler::SetConfig(config);
    session.reset(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    // Hiragana
    command.Clear();
    session->InputModeHiragana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Full-Katakana
    command.Clear();
    session->InputModeFullKatakana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Half-Katakana
    command.Clear();
    session->InputModeHalfKatakana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Full-ASCII
    command.Clear();
    session->InputModeFullASCII(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Half-ASCII
    command.Clear();
    session->InputModeHalfASCII(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
    // Direct
    command.Clear();
    session->IMEOff(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));

    // Set config to 'FULL' -- all mode except for DIRECT emits
    // full-width space.
    config.set_space_character_form(config::Config::FUNDAMENTAL_FULL_WIDTH);
    config::ConfigHandler::SetConfig(config);
    session.reset(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    // Hiragana
    command.Clear();
    session->InputModeHiragana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Full-Katakana
    command.Clear();
    session->InputModeFullKatakana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(command.input()));
    // Half-Katakana
    command.Clear();
    session->InputModeHalfKatakana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Full-ASCII
    command.Clear();
    session->InputModeFullASCII(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Half-ASCII
    command.Clear();
    session->InputModeHalfASCII(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(empty_input));
    // Direct
    command.Clear();
    session->IMEOff(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(empty_input));
  }

  { // When |input| has |input.key().mode()| field,
    // the specified input mode by |input| will be used.

    // Default config -- follow to the current mode.
    config.set_space_character_form(config::Config::FUNDAMENTAL_INPUT_MODE);
    config::ConfigHandler::SetConfig(config);
    session.reset(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    // Use HALF_KATAKANA for the new input mode
    commands::Input input;
    input.mutable_key()->set_mode(commands::HALF_KATAKANA);

    // Hiragana
    commands::Command command;
    session->InputModeHiragana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
    // Full-Katakana
    command.Clear();
    session->InputModeFullKatakana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
    // Half-Katakana
    command.Clear();
    session->InputModeHalfKatakana(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
    // Full-ASCII
    command.Clear();
    session->InputModeFullASCII(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
    // Half-ASCII
    command.Clear();
    session->InputModeHalfASCII(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
    // Direct
    command.Clear();
    session->IMEOff(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));

    // Use FULL_ASCII for the new input mode
    input.mutable_key()->set_mode(commands::FULL_ASCII);

    // Hiragana
    command.Clear();
    session->InputModeHiragana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(input));
    // Full-Katakana
    command.Clear();
    session->InputModeFullKatakana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(input));
    // Half-Katakana
    command.Clear();
    session->InputModeHalfKatakana(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(input));
    // Full-ASCII
    command.Clear();
    session->InputModeFullASCII(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(input));
    // Half-ASCII
    command.Clear();
    session->InputModeHalfASCII(&command);
    EXPECT_TRUE(session->IsFullWidthInsertSpace(input));
    // Direct
    command.Clear();
    session->IMEOff(&command);
    EXPECT_FALSE(session->IsFullWidthInsertSpace(input));
  }
}

TEST_F(SessionTest, Issue1951385) {
  // This is a unittest against http://b/1951385
  Segments segments;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  const string exceeded_preedit(500, 'a');
  ASSERT_EQ(500, exceeded_preedit.size());
  InsertCharacterChars(exceeded_preedit, session.get(), &command);

  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, false);

  command.Clear();
  session->ConvertToFullASCII(&command);
  EXPECT_FALSE(command.output().has_candidates());

  // The status should remain the preedit status, although the
  // previous command was convert.  The next command makes sure that
  // the preedit will disappear by canceling the preedit status.
  command.Clear();
  command.mutable_input()->mutable_key()->set_special_key(
      commands::KeyEvent::ESCAPE);
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, Issue1978201) {
  // This is a unittest against http://b/1978201
  Segments segments;
  Segment *segment;
  segment = segments.add_segment();
  // "いんぼう"
  segment->set_key("\xe3\x81\x84\xe3\x82\x93\xe3\x81\xbc\xe3\x81\x86");
  // "陰謀"
  segment->add_candidate()->value = "\xe9\x99\xb0\xe8\xac\x80";
  // "陰謀論"
  segment->add_candidate()->value = "\xe9\x99\xb0\xe8\xac\x80\xe8\xab\x96";
  // "陰謀説"
  segment->add_candidate()->value = "\xe9\x99\xb0\xe8\xac\x80\xe8\xaa\xac";
  GetConverterMock()->SetStartPredictionForRequest(&segments, true);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  EXPECT_TRUE(session->SegmentWidthShrink(&command));

  command.Clear();
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);
  EXPECT_TRUE(session->Convert(&command));

  command.Clear();
  EXPECT_TRUE(session->CommitSegment(&command));
  // "陰謀"
  EXPECT_RESULT("\xE9\x99\xB0\xE8\xAC\x80", command);
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, Issue1975771) {
  // This is a unittest against http://b/1975771
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Trigger suggest by pressing "a".
  Segments segments;
  SetAiueo(&segments);
  GetConverterMock()->SetStartSuggestionForRequest(&segments, true);

  commands::Command command;
  commands::KeyEvent* key_event = command.mutable_input()->mutable_key();
  key_event->set_key_code('a');
  key_event->set_modifiers(0);  // No modifiers.
  EXPECT_TRUE(session->InsertCharacter(&command));

  // Click the first candidate.
  SetSendCommandCommand(commands::SessionCommand::SELECT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(0);
  EXPECT_TRUE(session->SendCommand(&command));

  // After select candidate session->status_ should be
  // SessionStatus::CONVERSION.

  SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
  EXPECT_TRUE(command.output().has_candidates());
  // The second candidate should be selected.
  EXPECT_EQ(1, command.output().candidates().focused_index());
}

TEST_F(SessionTest, Issue2029466) {
  // This is a unittest against http://b/2029466
  //
  // "a<tab><ctrl-N>a" raised an exception because CommitFirstSegment
  // did not check if the current status is in conversion or
  // precomposition.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // "a"
  commands::Command command;
  InsertCharacterChars("a", session.get(), &command);

  // <tab>
  Segments segments;
  SetAiueo(&segments);
  GetConverterMock()->SetStartPredictionForRequest(&segments, true);
  command.Clear();
  EXPECT_TRUE(session->PredictAndConvert(&command));

  // <ctrl-N>
  segments.Clear();
  // FinishConversion is expected to return empty Segments.
  GetConverterMock()->SetFinishConversion(&segments, true);
  command.Clear();
  EXPECT_TRUE(session->CommitSegment(&command));

  // "a"
  InsertCharacterChars("a", session.get(), &command);
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);
  EXPECT_FALSE(command.output().has_candidates());
}

TEST_F(SessionTest, Issue2034943) {
  // This is a unittest against http://b/2029466
  //
  // The composition should have been reset if CommitSegment submitted
  // the all segments (e.g. the size of segments is one).
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("mozu", session.get(), &command);

  {  // Initialize a suggest result triggered by "mozu".
    Segments segments;
    Segment *segment = segments.add_segment();
    segment->set_key("mozu");
    Segment::Candidate *candidate;
    candidate = segment->add_candidate();
    candidate->value = "MOZU";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }
  // Get conversion
  command.Clear();
  EXPECT_TRUE(session->Convert(&command));

  // submit segment
  command.Clear();
  EXPECT_TRUE(session->CommitSegment(&command));

  // The composition should have been reset.
  InsertCharacterChars("ku", session.get(), &command);
  // "く"
  EXPECT_EQ("\343\201\217", command.output().preedit().segment(0).value());
}

TEST_F(SessionTest, Issue2026354) {
  // This is a unittest against http://b/2026354
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);

  // Trigger suggest by pressing "a".
  Segments segments;
  SetAiueo(&segments);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  EXPECT_TRUE(session->Convert(&command));

  //  EXPECT_TRUE(session->ConvertNext(&command));
  TestSendKey("Space", session.get(), &command);
  EXPECT_PREEDIT(kAiueo, command);
  command.mutable_output()->clear_candidates();
  EXPECT_FALSE(command.output().has_candidates());
}

TEST_F(SessionTest, Issue2066906) {
  // This is a unittest against http://b/2066906
  Segments segments;
  Segment *segment;
  Segment::Candidate *candidate;
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  segment = segments.add_segment();
  segment->set_key("a");
  candidate = segment->add_candidate();
  candidate->value = "abc";
  candidate = segment->add_candidate();
  candidate->value = "abcdef";
  GetConverterMock()->SetStartPredictionForRequest(&segments, true);

  // Prediction with "a"
  commands::Command command;
  EXPECT_TRUE(session->PredictAndConvert(&command));
  EXPECT_FALSE(command.output().has_result());

  // Commit
  command.Clear();
  EXPECT_TRUE(session->Commit(&command));
  EXPECT_RESULT("abc", command);

  GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
  InsertCharacterChars("a", session.get(), &command);
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, Issue2187132) {
  // This is a unittest against http://b/2187132
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // Shift + Ascii triggers temporary input mode switch.
  SendKey("A", session.get(), &command);
  SendKey("Enter", session.get(), &command);

  // After submission, input mode should be reverted.
  SendKey("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  command.Clear();
  session->EditCancel(&command);
  EXPECT_TRUE(GetComposition(command).empty());

  // If a user intentionally switched an input mode, it should remain.
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  SendKey("A", session.get(), &command);
  SendKey("Enter", session.get(), &command);
  SendKey("a", session.get(), &command);
  EXPECT_EQ("a", GetComposition(command));
}

TEST_F(SessionTest, Issue2190364) {
  // This is a unittest against http://b/2190364
  config::Config config;
  config.set_preedit_method(config::Config::KANA);
  config::ConfigHandler::SetConfig(config);
  ASSERT_EQ(config::Config::KANA, GET_CONFIG(preedit_method));

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  session->ToggleAlphanumericMode(&command);

  // "ち"
  InsertCharacterCodeAndString('a', "\xE3\x81\xA1", session.get(), &command);
  EXPECT_EQ("a", GetComposition(command));

  command.Clear();
  session->ToggleAlphanumericMode(&command);
  EXPECT_EQ("a", GetComposition(command));

  // "に"
  InsertCharacterCodeAndString('i', "\xE3\x81\xAB", session.get(), &command);
  // "aに"
  EXPECT_EQ("a\xE3\x81\xAB", GetComposition(command));
}

TEST_F(SessionTest, Issue1556649) {
  // This is a unittest against http://b/1556649
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("kudoudesu", session.get(), &command);
  // "くどうです"
  EXPECT_EQ("\xE3\x81\x8F\xE3\x81\xA9\xE3\x81\x86\xE3\x81\xA7\xE3\x81\x99",
            GetComposition(command));
  EXPECT_EQ(5, command.output().preedit().cursor());

  command.Clear();
  EXPECT_TRUE(session->DisplayAsHalfKatakana(&command));
  // "ｸﾄﾞｳﾃﾞｽ"
  EXPECT_EQ("\xEF\xBD\xB8\xEF\xBE\x84\xEF\xBE\x9E\xEF\xBD\xB3\xEF\xBE\x83"
            "\xEF\xBE\x9E\xEF\xBD\xBD",
            GetComposition(command));
  EXPECT_EQ(7, command.output().preedit().cursor());

  for (size_t i = 0; i < 7; ++i) {
    const size_t expected_pos = 6 - i;
    EXPECT_TRUE(SendKey("Left", session.get(), &command));
    EXPECT_EQ(expected_pos, command.output().preedit().cursor());
  }
}

TEST_F(SessionTest, Issue1518994) {
  // This is a unittest against http://b/1518994.
  // - Can't input space in ascii mode.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    command.Clear();
    EXPECT_TRUE(session->ToggleAlphanumericMode(&command));
    EXPECT_TRUE(SendKey("i", session.get(), &command));
    // "あi"
    EXPECT_EQ("\xE3\x81\x82\x69", GetComposition(command));

    EXPECT_TRUE(SendKey("Space", session.get(), &command));
    // "あi "
    EXPECT_EQ("\xE3\x81\x82\x69\x20", GetComposition(command));
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;
    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(SendKey("I", session.get(), &command));
    // "あI"
    EXPECT_EQ("\xE3\x81\x82\x49", GetComposition(command));

    EXPECT_TRUE(SendKey("Space", session.get(), &command));
    // "あI "
    EXPECT_EQ("\xE3\x81\x82\x49\x20", GetComposition(command));
  }
}

TEST_F(SessionTest, Issue1571043) {
  // This is a unittest against http://b/1571043.
  // - Underline of composition is separated.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("aiu", session.get(), &command);
  // "あいう"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86", GetComposition(command));

  for (size_t i = 0; i < 3; ++i) {
    const size_t expected_pos = 2 - i;
    EXPECT_TRUE(SendKey("Left", session.get(), &command));
    EXPECT_EQ(expected_pos, command.output().preedit().cursor());
    EXPECT_EQ(1, command.output().preedit().segment_size());
  }
}

TEST_F(SessionTest, Issue1799384) {
  // This is a unittest against http://b/1571043.
  // - ConvertToHiragana converts Vu to U+3094 "ヴ"
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("ravu", session.get(), &command);
  // TODO(komatsu) "ヴ" might be preferred on Mac.
  // "らヴ"
  EXPECT_EQ("\xE3\x82\x89\xE3\x83\xB4", GetComposition(command));

  {  // Initialize GetConverterMock() to generate t13n candidates.
    Segments segments;
    Segment *segment;
    segments.set_request_type(Segments::CONVERSION);
    segment = segments.add_segment();
    // "らヴ"
    segment->set_key("\xE3\x82\x89\xE3\x83\xB4");
    Segment::Candidate *candidate;
    candidate = segment->add_candidate();
    // "らぶ"
    candidate->value = "\xE3\x82\x89\xE3\x81\xB6";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  command.Clear();
  EXPECT_TRUE(session->ConvertToHiragana(&command));

  // "らヴ"
  EXPECT_EQ("\xE3\x82\x89\xE3\x83\xB4", GetComposition(command));
}

TEST_F(SessionTest, Issue2217250) {
  // This is a unittest against http://b/2217250.
  // Temporary direct input mode through a special sequence such as
  // www. continues even after committing them
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  InsertCharacterChars("www.", session.get(), &command);
  EXPECT_EQ("www.", GetComposition(command));
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  SendKey("Enter", session.get(), &command);
  EXPECT_EQ("www.", command.output().result().value());
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
}

TEST_F(SessionTest, Issue2223823) {
  // This is a unittest against http://b/2223823
  // Input mode does not recover like MS-IME by single shift key down
  // and up.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  SendKey("G", session.get(), &command);
  EXPECT_EQ("G", GetComposition(command));
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  SendKey("Shift", session.get(), &command);
  EXPECT_EQ("G", GetComposition(command));
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
}


TEST_F(SessionTest, Issue2223762) {
  // This is a unittest against http://b/2223762.
  // - The first space in half-width alphanumeric mode is full-width.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, Issue2223755) {
  // This is a unittest against http://b/2223755.
  // - F6 and F7 convert space to half-width.

  {  // DisplayAsFullKatakana
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(SendKey("Eisu", session.get(), &command));
    EXPECT_TRUE(SendKey("Space", session.get(), &command));
    EXPECT_TRUE(SendKey("Eisu", session.get(), &command));
    EXPECT_TRUE(SendKey("i", session.get(), &command));

    // "あ い"
    EXPECT_EQ("\xE3\x81\x82\x20\xE3\x81\x84", GetComposition(command));

    command.Clear();
    EXPECT_TRUE(session->DisplayAsFullKatakana(&command));

    // "ア　イ"(fullwidth space)
    EXPECT_EQ("\xE3\x82\xA2\xE3\x80\x80\xE3\x82\xA4", GetComposition(command));
  }

  {  // ConvertToFullKatakana
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    EXPECT_TRUE(SendKey("a", session.get(), &command));
    EXPECT_TRUE(SendKey("Eisu", session.get(), &command));
    EXPECT_TRUE(SendKey("Space", session.get(), &command));
    EXPECT_TRUE(SendKey("Eisu", session.get(), &command));
    EXPECT_TRUE(SendKey("i", session.get(), &command));

    // "あ い"
    EXPECT_EQ("\xE3\x81\x82\x20\xE3\x81\x84", GetComposition(command));

    {  // Initialize GetConverterMock() to generate t13n candidates.
      Segments segments;
      Segment *segment;
      segments.set_request_type(Segments::CONVERSION);
      segment = segments.add_segment();
      // "あ い"
      segment->set_key("\xE3\x81\x82\x20\xE3\x81\x84");
      Segment::Candidate *candidate;
      candidate = segment->add_candidate();
      // "あ い"
      candidate->value = "\xE3\x81\x82\x20\xE3\x81\x84";
      ConversionRequest request;
      SetComposer(session.get(), &request);
      FillT13Ns(request, &segments);
      GetConverterMock()->SetStartConversionForRequest(&segments, true);
    }

    command.Clear();
    EXPECT_TRUE(session->ConvertToFullKatakana(&command));

    // "ア　イ"(fullwidth space)
    EXPECT_EQ("\xE3\x82\xA2\xE3\x80\x80\xE3\x82\xA4", GetComposition(command));
  }
}

TEST_F(SessionTest, Issue2269058) {
  // This is a unittest against http://b/2269058.
  // - Temporary input mode should not be overridden by a permanent
  //   input mode change.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  EXPECT_TRUE(SendKey("G", session.get(), &command));
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  command.Clear();
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

  EXPECT_TRUE(SendKey("Shift", session.get(), &command));
  EXPECT_EQ(commands::HIRAGANA, command.output().mode());
}

TEST_F(SessionTest, Issue2272745) {
  // This is a unittest against http://b/2272745.
  // A temporary input mode remains when a composition is canceled.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    EXPECT_TRUE(SendKey("G", session.get(), &command));
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(SendKey("Backspace", session.get(), &command));
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    EXPECT_TRUE(SendKey("G", session.get(), &command));
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(SendKey("Escape", session.get(), &command));
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }
}

TEST_F(SessionTest, Issue2282319) {
  // This is a unittest against http://b/2282319.
  // InsertFullSpace is not working in half-width input mode.
  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  ASSERT_EQ(config::Config::MSIME, GET_CONFIG(session_keymap));

  commands::Command command;
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());

  EXPECT_TRUE(TestSendKey("a", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  EXPECT_TRUE(SendKey("a", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_PREEDIT("a", command);

  EXPECT_TRUE(TestSendKey("Ctrl Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());

  EXPECT_TRUE(SendKey("Ctrl Shift Space", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_PREEDIT(string("a") + kFullWidthSpace, command);
}

TEST_F(SessionTest, Issue2297060) {
  // This is a unittest against http://b/2297060.
  // Ctrl-Space is not working
  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  ASSERT_EQ(config::Config::MSIME, GET_CONFIG(session_keymap));

  commands::Command command;
  EXPECT_TRUE(SendKey("Ctrl Space", session.get(), &command));
  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, Issue2379374) {
  // This is a unittest against http://b/2379374.
  // Numpad ignores Direct input style when typing after conversion.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  {  // Set numpad_character_form with NUMPAD_DIRECT_INPUT
    config::Config config;
    config.set_numpad_character_form(config::Config::NUMPAD_DIRECT_INPUT);
    config::ConfigHandler::SetConfig(config);
    ASSERT_EQ(config::Config::NUMPAD_DIRECT_INPUT,
              GET_CONFIG(numpad_character_form));
    // Update KeyEventTransformer.
    session->ReloadConfig();
  }

  Segments segments;
  {  // Set mock conversion.
    Segment *segment;
    Segment::Candidate *candidate;

    segment = segments.add_segment();
    // "あ"
    segment->set_key(kHiraganaA);
    candidate = segment->add_candidate();
    // "亜"
    candidate->value = "\xE4\xBA\x9C";
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  EXPECT_TRUE(SendKey("a", session.get(), &command));
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  EXPECT_TRUE(SendKey("Space", session.get(), &command));
  // "亜"
  EXPECT_EQ("\xE4\xBA\x9C", GetComposition(command));

  EXPECT_TRUE(SendKey("Numpad0", session.get(), &command));
  EXPECT_TRUE(GetComposition(command).empty());
  // "亜0", "あ0"
  EXPECT_RESULT_AND_KEY("\xE4\xBA\x9C\x30", "\xE3\x81\x82\x30", command);

  // The previous Numpad0 must not affect the current composition.
  EXPECT_TRUE(SendKey("a", session.get(), &command));
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));
}

TEST_F(SessionTest, Issue2569789) {
  // This is a unittest against http://b/2379374.
  // After typing "google", the input mode does not come back to the
  // previous input mode.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    InsertCharacterChars("google", session.get(), &command);
    EXPECT_EQ("google", GetComposition(command));
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    EXPECT_TRUE(SendKey("enter", session.get(), &command));
    ASSERT_TRUE(command.output().has_result());
    EXPECT_EQ("google", command.output().result().value());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    InsertCharacterChars("Google", session.get(), &command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(SendKey("enter", session.get(), &command));
    ASSERT_TRUE(command.output().has_result());
    EXPECT_EQ("Google", command.output().result().value());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    InsertCharacterChars("Google", session.get(), &command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(SendKey("shift", session.get(), &command));
    EXPECT_EQ("Google", GetComposition(command));
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    InsertCharacterChars("aaa", session.get(), &command);
    // "Googleあああ"
    EXPECT_EQ("Google\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82",
              GetComposition(command));
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    InsertCharacterChars("http", session.get(), &command);
    EXPECT_EQ(commands::HALF_ASCII, command.output().mode());

    EXPECT_TRUE(SendKey("enter", session.get(), &command));
    ASSERT_TRUE(command.output().has_result());
    EXPECT_EQ("http", command.output().result().value());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
  }
}

TEST_F(SessionTest, Issue2555503) {
  // This is a unittest against http://b/2555503.
  // Mode respects the previous character too much.

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  SendKey("a", session.get(), &command);

  command.Clear();
  session->InputModeFullKatakana(&command);

  SendKey("i", session.get(), &command);
  // "あイ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x82\xA4", GetComposition(command));

  SendKey("backspace", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));
  EXPECT_EQ(commands::FULL_KATAKANA, command.output().mode());
}

TEST_F(SessionTest, Issue2791640) {
  // This is a unittest against http://b/2791640.
  // Existing preedit should be committed when IME is turned off.

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  SendKey("a", session.get(), &command);
  SendKey("hankaku/zenkaku", session.get(), &command);

  ASSERT_TRUE(command.output().consumed());

  ASSERT_TRUE(command.output().has_result());
  // "あ"
  EXPECT_EQ(kHiraganaA, command.output().result().value());
  EXPECT_EQ(commands::DIRECT, command.output().mode());

  ASSERT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, CommitExistingPreeditWhenIMEIsTurnedOff) {
  // Existing preedit should be committed when IME is turned off.

  // Check "hankaku/zenkaku"
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    SendKey("a", session.get(), &command);
    SendKey("hankaku/zenkaku", session.get(), &command);

    ASSERT_TRUE(command.output().consumed());

    ASSERT_TRUE(command.output().has_result());
    // "あ"
    EXPECT_EQ(kHiraganaA, command.output().result().value());
    EXPECT_EQ(commands::DIRECT, command.output().mode());

    ASSERT_FALSE(command.output().has_preedit());
  }

  // Check "kanji"
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;
    SendKey("a", session.get(), &command);
    SendKey("kanji", session.get(), &command);

    ASSERT_TRUE(command.output().consumed());

    ASSERT_TRUE(command.output().has_result());
    // "あ"
    EXPECT_EQ(kHiraganaA, command.output().result().value());
    EXPECT_EQ(commands::DIRECT, command.output().mode());

    ASSERT_FALSE(command.output().has_preedit());
  }
}


TEST_F(SessionTest, SendKeyDirectInputStateTest) {
  // InputModeChange commands from direct mode are supported only for Windows
  // for now.
#ifdef OS_WIN
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToDirect(session.get());
  commands::Command command;

  config::Config config;
  const string custom_keymap_table =
      "status\tkey\tcommand\n"
      "DirectInput\tHiragana\tInputModeHiragana\n";
  config.set_session_keymap(config::Config::CUSTOM);
  config.set_custom_keymap_table(custom_keymap_table);
  config::ConfigHandler::SetConfig(config);

  EXPECT_TRUE(SendKey("Hiragana", session.get(), &command));
  EXPECT_TRUE(SendKey("a", session.get(), &command));
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);
#endif  // OS_WIN
}

TEST_F(SessionTest, HandlingDirectInputTableAttribute) {
  composer::Table table;
  // "か"
  table.AddRuleWithAttributes("ka", "\xE3\x81\x8B", "",
                              composer::DIRECT_INPUT);
  // "っ"
  table.AddRuleWithAttributes("tt", "\xE3\x81\xA3", "t",
                              composer::DIRECT_INPUT);
  // "た"
  table.AddRuleWithAttributes("ta", "\xE3\x81\x9F", "",
                              composer::NO_TABLE_ATTRIBUTE);

  Session session(engine_.get());
  InitSessionToPrecomposition(&session);
  session.get_internal_composer_only_for_unittest()->SetTable(&table);

  commands::Command command;
  SendKey("k", &session, &command);
  EXPECT_FALSE(command.output().has_result());

  SendKey("a", &session, &command);
  // "か"
  EXPECT_RESULT("\xE3\x81\x8B", command);

  SendKey("t", &session, &command);
  EXPECT_FALSE(command.output().has_result());

  SendKey("t", &session, &command);
  EXPECT_FALSE(command.output().has_result());

  SendKey("a", &session, &command);
  // "った"
  EXPECT_RESULT("\xE3\x81\xA3\xE3\x81\x9F", command);
}

TEST_F(SessionTest, IMEOnWithModeTest) {
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;
    command.mutable_input()->mutable_key()->set_mode(
        commands::HIRAGANA);
    EXPECT_TRUE(session->IMEOn(&command));
    EXPECT_TRUE(command.output().has_consumed());
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HIRAGANA,
              command.output().mode());
    SendKey("a", session.get(), &command);
    // "あ"
    EXPECT_SINGLE_SEGMENT(kHiraganaA, command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;
    command.mutable_input()->mutable_key()->set_mode(
        commands::FULL_KATAKANA);
    EXPECT_TRUE(session->IMEOn(&command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::FULL_KATAKANA,
              command.output().mode());
    SendKey("a", session.get(), &command);
    // "ア"
    EXPECT_SINGLE_SEGMENT("\xE3\x82\xA2", command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;
    command.mutable_input()->mutable_key()->set_mode(
        commands::HALF_KATAKANA);
    EXPECT_TRUE(session->IMEOn(&command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_KATAKANA,
              command.output().mode());
    SendKey("a", session.get(), &command);
    // "ｱ" (half-width Katakana)
    EXPECT_SINGLE_SEGMENT("\xEF\xBD\xB1", command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;
    command.mutable_input()->mutable_key()->set_mode(
        commands::FULL_ASCII);
    EXPECT_TRUE(session->IMEOn(&command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::FULL_ASCII,
              command.output().mode());
    SendKey("a", session.get(), &command);
    // "ａ"
    EXPECT_SINGLE_SEGMENT("\xEF\xBD\x81", command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToDirect(session.get());

    commands::Command command;
    command.mutable_input()->mutable_key()->set_mode(
        commands::HALF_ASCII);
    EXPECT_TRUE(session->IMEOn(&command));
    EXPECT_TRUE(command.output().has_mode());
    EXPECT_EQ(commands::HALF_ASCII,
              command.output().mode());
    SendKey("a", session.get(), &command);
    // "a"
    EXPECT_SINGLE_SEGMENT("a", command);
  }
}

TEST_F(SessionTest, InputModeConsumed) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  EXPECT_TRUE(session->InputModeHiragana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HIRAGANA, command.output().mode());
  command.Clear();
  EXPECT_TRUE(session->InputModeFullKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_KATAKANA, command.output().mode());
  command.Clear();
  EXPECT_TRUE(session->InputModeHalfKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_KATAKANA, command.output().mode());
  command.Clear();
  EXPECT_TRUE(session->InputModeFullASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_ASCII, command.output().mode());
  command.Clear();
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());
}

TEST_F(SessionTest, InputModeConsumedForTestSendKey) {
  // This test is only for Windows, because InputModeHiragana bound
  // with Hiragana key is only supported on Windows yet.
#ifdef OS_WIN
  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  ASSERT_EQ(config::Config::MSIME, GET_CONFIG(session_keymap));
  // In MSIME keymap, Hiragana is assigned for
  // ImputModeHiragana in Precomposition.

  commands::Command command;
  EXPECT_TRUE(TestSendKey("Hiragana", session.get(), &command));
  EXPECT_TRUE(command.output().consumed());
#endif  // OS_WIN
}

TEST_F(SessionTest, InputModeOutputHasComposition) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  SendKey("a", session.get(), &command);
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  command.Clear();
  EXPECT_TRUE(session->InputModeHiragana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HIRAGANA, command.output().mode());
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  command.Clear();
  EXPECT_TRUE(session->InputModeFullKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_KATAKANA, command.output().mode());
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  command.Clear();
  EXPECT_TRUE(session->InputModeHalfKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_KATAKANA, command.output().mode());
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  command.Clear();
  EXPECT_TRUE(session->InputModeFullASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_ASCII, command.output().mode());
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);

  command.Clear();
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());
  // "あ"
  EXPECT_SINGLE_SEGMENT(kHiraganaA, command);
}

TEST_F(SessionTest, InputModeOutputHasCandidates) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  Segments segments;
  SetAiueo(&segments);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  commands::Command command;
  InsertCharacterChars("aiueo", session.get(), &command);

  command.Clear();
  session->Convert(&command);
  session->ConvertNext(&command);
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());

  command.Clear();
  EXPECT_TRUE(session->InputModeHiragana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HIRAGANA, command.output().mode());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());

  command.Clear();
  EXPECT_TRUE(session->InputModeFullKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_KATAKANA, command.output().mode());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());

  command.Clear();
  EXPECT_TRUE(session->InputModeHalfKatakana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_KATAKANA, command.output().mode());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());

  command.Clear();
  EXPECT_TRUE(session->InputModeFullASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::FULL_ASCII, command.output().mode());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());

  command.Clear();
  EXPECT_TRUE(session->InputModeHalfASCII(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HALF_ASCII, command.output().mode());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_TRUE(command.output().has_preedit());
}

TEST_F(SessionTest, PerformedCommand) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  {
    commands::Command command;
    // IMEOff
    EXPECT_STATS_NOT_EXIST("Performed_Precomposition_IMEOff");
    SendSpecialKey(commands::KeyEvent::OFF, session.get(), &command);
    EXPECT_COUNT_STATS("Performed_Precomposition_IMEOff", 1);
  }
  {
    commands::Command command;
    // IMEOn
    EXPECT_STATS_NOT_EXIST("Performed_Direct_IMEOn");
    SendSpecialKey(commands::KeyEvent::ON, session.get(), &command);
    EXPECT_COUNT_STATS("Performed_Direct_IMEOn", 1);
  }
  {
    commands::Command command;
    // 'a'
    EXPECT_STATS_NOT_EXIST("Performed_Precomposition_InsertCharacter");
    SendKey("a", session.get(), &command);
    EXPECT_COUNT_STATS("Performed_Precomposition_InsertCharacter", 1);
  }
  {
    // SetStartConversion for changing state to Convert.
    Segments segments;
    SetAiueo(&segments);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    FillT13Ns(request, &segments);
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    commands::Command command;
    // SPACE
    EXPECT_STATS_NOT_EXIST("Performed_Composition_Convert");
    SendSpecialKey(commands::KeyEvent::SPACE, session.get(), &command);
    EXPECT_COUNT_STATS("Performed_Composition_Convert", 1);
  }
  {
    commands::Command command;
    // ENTER
    EXPECT_STATS_NOT_EXIST("Performed_Conversion_Commit");
    SendSpecialKey(commands::KeyEvent::ENTER, session.get(), &command);
    EXPECT_COUNT_STATS("Performed_Conversion_Commit", 1);
  }
}

TEST_F(SessionTest, ResetContext) {
  scoped_ptr<MockConverterEngineForReset> engine(
      new MockConverterEngineForReset);
  ConverterMockForReset *convertermock = engine->mutable_converter_mock();

  scoped_ptr<Session> session(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  session->ResetContext(&command);
  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(convertermock->reset_conversion_called());

  convertermock->Reset();
  EXPECT_TRUE(SendKey("A", session.get(), &command));
  command.Clear();
  session->ResetContext(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_TRUE(convertermock->reset_conversion_called());
}

TEST_F(SessionTest, ClearUndoOnResetContext) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  commands::Command command;
  Segments segments;

  {  // Create segments
    InsertCharacterChars("aiueo", session.get(), &command);
    ConversionRequest request;
    SetComposer(session.get(), &request);
    SetAiueo(&segments);
    // Don't use FillT13Ns(). It makes platform dependent segments.
    // TODO(hsumita): Makes FillT13Ns() independent from platforms.
    Segment::Candidate *candidate;
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "aiueo";
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "AIUEO";
  }

  {
    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session->Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    // "あいうえお"
    EXPECT_SINGLE_SEGMENT(kAiueo, command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session->Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);

    command.Clear();
    session->ResetContext(&command);

    command.Clear();
    session->Undo(&command);
    // After reset, undo shouldn't run.
    EXPECT_FALSE(command.output().has_preedit());
  }
}

TEST_F(SessionTest, IssueResetConversion) {
  scoped_ptr<MockConverterEngineForReset> engine(
      new MockConverterEngineForReset);
  ConverterMockForReset *convertermock = engine->mutable_converter_mock();

  scoped_ptr<Session> session(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // any meaneangless key calls ResetConversion
  EXPECT_FALSE(convertermock->reset_conversion_called());
  EXPECT_TRUE(SendKey("enter", session.get(), &command));
  EXPECT_TRUE(convertermock->reset_conversion_called());

  convertermock->Reset();
  EXPECT_FALSE(convertermock->reset_conversion_called());
  EXPECT_TRUE(SendKey("space", session.get(), &command));
  EXPECT_TRUE(convertermock->reset_conversion_called());
}

TEST_F(SessionTest, IssueRevert) {
  scoped_ptr<MockConverterEngineForRevert> engine(
      new MockConverterEngineForRevert);
  ConverterMockForRevert *convertermock = engine->mutable_converter_mock();

  scoped_ptr<Session> session(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  // changes the state to PRECOMPOSITION
  session->IMEOn(&command);

  session->Revert(&command);

  EXPECT_FALSE(command.output().consumed());
  EXPECT_TRUE(convertermock->revert_conversion_called());
}

// Undo command must call RervertConversion
TEST_F(SessionTest, Issue3428520) {
  scoped_ptr<MockConverterEngineForRevert> engine(
      new MockConverterEngineForRevert);
  ConverterMockForRevert *convertermock = engine->mutable_converter_mock();

  scoped_ptr<Session> session(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  commands::Command command;
  Segments segments;

  InsertCharacterChars("aiueo", session.get(), &command);
  ConversionRequest request;
  SetComposer(session.get(), &request);
  SetAiueo(&segments);
  FillT13Ns(request, &segments);
  convertermock->SetStartConversionForRequest(&segments, true);

  command.Clear();
  session->Convert(&command);
  EXPECT_FALSE(command.output().has_result());
  // "あいうえお"
  EXPECT_SINGLE_SEGMENT(kAiueo, command);

  convertermock->SetCommitSegmentValue(&segments, true);
  command.Clear();
  session->Commit(&command);
  EXPECT_FALSE(command.output().has_preedit());
  // "あいうえお"
  EXPECT_RESULT(kAiueo, command);

  command.Clear();
  session->Undo(&command);

  // After check the status of revert_conversion_called.
  EXPECT_TRUE(convertermock->revert_conversion_called());
}

// Revert command must clear the undo context.
TEST_F(SessionTest, Issue5742293) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session->set_client_capability(capability);

  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);

  SetUndoContext(session.get());

  commands::Command command;

  // BackSpace key event issues Revert command, which should clear the undo
  // context.
  EXPECT_TRUE(SendKey("Backspace", session.get(), &command));

  // Ctrl+BS should be consumed as UNDO.
  EXPECT_TRUE(TestSendKey("Ctrl Backspace", session.get(), &command));

  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, AutoConversion) {
  Segments segments;
  SetAiueo(&segments);
  ConversionRequest default_request;
  FillT13Ns(default_request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  // Auto Off
  config::Config config;
  config.set_use_auto_conversion(false);
  config::ConfigHandler::SetConfig(config);
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    InsertCharacterChars("tesuto.", session.get(), &command);

    // "てすと。",
    EXPECT_SINGLE_SEGMENT_AND_KEY(
        "\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82",
        "\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82", command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    // "てすと。"
    InsertCharacterString("\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82",
                          "wrs/", session.get(), &command);

    // "てすと。",
    EXPECT_SINGLE_SEGMENT_AND_KEY(
        "\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82",
        "\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82", command);
  }

  // Auto On
  config.set_use_auto_conversion(true);
  config::ConfigHandler::SetConfig(config);
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;

    // The last "." is a triggering key for auto conversion
    InsertCharacterChars("tesuto.", session.get(), &command);

    EXPECT_SINGLE_SEGMENT_AND_KEY(kAiueo, kAiueo, command);
  }
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    commands::Command command;

    // The last "." is a triggering key for auto conversion
    // "てすと。",
    InsertCharacterString("\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8\xE3\x80\x82",
                          "wrs/", session.get(), &command);

    EXPECT_SINGLE_SEGMENT_AND_KEY(kAiueo, kAiueo, command);
  }

  // Don't trigger auto conversion for the pattern number + "."
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    InsertCharacterChars("123.", session.get(), &command);

    // "１２３．"
    EXPECT_SINGLE_SEGMENT_AND_KEY(
        "\xEF\xBC\x91\xEF\xBC\x92\xEF\xBC\x93\xEF\xBC\x8E",
        "\xEF\xBC\x91\xEF\xBC\x92\xEF\xBC\x93\xEF\xBC\x8E", command);
  }

  // Don't trigger auto conversion for the ".."
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    InsertCharacterChars("..", session.get(), &command);

    // "。。"
    EXPECT_SINGLE_SEGMENT_AND_KEY(
        "\xE3\x80\x82\xE3\x80\x82", "\xE3\x80\x82\xE3\x80\x82", command);
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    // "１２３。"
    InsertCharacterString("\xEF\xBC\x91\xEF\xBC\x92\xEF\xBC\x93\xE3\x80\x82",
                          "123.", session.get(), &command);

    // "１２３．"
    EXPECT_SINGLE_SEGMENT_AND_KEY(
        "\xEF\xBC\x91\xEF\xBC\x92\xEF\xBC\x93\xEF\xBC\x8E",
        "\xEF\xBC\x91\xEF\xBC\x92\xEF\xBC\x93\xEF\xBC\x8E", command);
  }

  // Don't trigger auto conversion for "." only.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    InsertCharacterChars(".", session.get(), &command);

    // "。"
    EXPECT_SINGLE_SEGMENT_AND_KEY("\xE3\x80\x82", "\xE3\x80\x82", command);
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());
    commands::Command command;

    // The last "." is a triggering key for auto conversion
    // "。",
    InsertCharacterString("\xE3\x80\x82", "/", session.get(), &command);

    // "。"
    EXPECT_SINGLE_SEGMENT_AND_KEY("\xE3\x80\x82", "\xE3\x80\x82", command);
  }

  // Do auto conversion even if romanji-table is modified.
  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get());

    // Modify romanji-table to convert "zz" -> "。"
    composer::Table zz_table;
    // "てすと。"
    zz_table.AddRule("te", "\xE3\x81\xA6", "");
    zz_table.AddRule("su", "\xE3\x81\x99", "");
    zz_table.AddRule("to", "\xE3\x81\xA8", "");
    zz_table.AddRule("zz", "\xE3\x80\x82", "");
    session->get_internal_composer_only_for_unittest()->SetTable(&zz_table);

    // The last "zz" is converted to "." and triggering key for auto conversion
    commands::Command command;
    InsertCharacterChars("tesutozz", session.get(), &command);

    EXPECT_SINGLE_SEGMENT_AND_KEY(kAiueo, kAiueo, command);
  }

  {
    const char trigger_key[] = ".,?!";

    // try all possible patterns.
    for (int kana_mode = 0; kana_mode < 2; ++kana_mode) {
      for (int onoff = 0; onoff < 2; ++onoff) {
        for (int pattern = 0; pattern <= 16; ++pattern) {
          config.set_use_auto_conversion(onoff != 0);
          config.set_auto_conversion_key(pattern);
          config::ConfigHandler::SetConfig(config);

          int flag[4];
          flag[0] = static_cast<int>(
              config.auto_conversion_key() &
              config::Config::AUTO_CONVERSION_KUTEN);
          flag[1] = static_cast<int>(
              config.auto_conversion_key() &
              config::Config::AUTO_CONVERSION_TOUTEN);
          flag[2] = static_cast<int>(
              config.auto_conversion_key() &
              config::Config::AUTO_CONVERSION_QUESTION_MARK);
          flag[3] = static_cast<int>(
              config.auto_conversion_key() &
              config::Config::AUTO_CONVERSION_EXCLAMATION_MARK);

          for (int i = 0; i < 4; ++i) {
            scoped_ptr<Session> session(new Session(engine_.get()));
            InitSessionToPrecomposition(session.get());
            commands::Command command;

            if (kana_mode) {
              // "てすと"
              string key = "\xE3\x81\xA6\xE3\x81\x99\xE3\x81\xA8";
              key += trigger_key[i];
              InsertCharacterString(key, "wst/", session.get(), &command);
            } else {
              string key = "tesuto";
              key += trigger_key[i];
              InsertCharacterChars(key, session.get(), &command);
            }
            EXPECT_TRUE(command.output().has_preedit());
            EXPECT_EQ(1, command.output().preedit().segment_size());
            EXPECT_TRUE(command.output().preedit().segment(0).has_value());
            EXPECT_TRUE(command.output().preedit().segment(0).has_key());

            if (onoff > 0 && flag[i] > 0) {
              // "あいうえお"
              EXPECT_EQ("\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86"
                        "\xe3\x81\x88\xe3\x81\x8a",
                        command.output().preedit().segment(0).key());
            } else {
              // Not "あいうえお"
              EXPECT_NE("\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86"
                        "\xe3\x81\x88\xe3\x81\x8a",
                        command.output().preedit().segment(0).key());
            }
          }
        }
      }
    }
  }
}

TEST_F(SessionTest, InputSpaceWithKatakanaMode) {
  // This is a unittest against http://b/3203944.
  // Input mode should not be changed when a space key is typed.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  EXPECT_TRUE(session->InputModeHiragana(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(mozc::commands::HIRAGANA, command.output().mode());

  SetSendKeyCommand("Space", &command);
  command.mutable_input()->mutable_key()->set_mode(commands::FULL_KATAKANA);
  EXPECT_TRUE(session->SendKey(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_RESULT(kFullWidthSpace, command);
  EXPECT_EQ(mozc::commands::FULL_KATAKANA, command.output().mode());
}

TEST_F(SessionTest, AlphanumericOfSSH) {
  // This is a unittest against http://b/3199626
  // 'ssh' (っｓｈ) + F10 should be 'ssh'.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  InsertCharacterChars("ssh", session.get(), &command);
  // "っｓｈ"
  EXPECT_EQ("\xE3\x81\xA3\xEF\xBD\x93\xEF\xBD\x88", GetComposition(command));

  Segments segments;
  // Set a dummy segments for ConvertToHalfASCII.
  {
    Segment *segment;
    segment = segments.add_segment();
    //    // "っｓｈ"
    //    segment->set_key("\xE3\x81\xA3\xEF\xBD\x93\xEF\xBD\x88");
    // "っsh"
    segment->set_key("\xE3\x81\xA3sh");

    segment->add_candidate()->value = "[SSH]";
  }
  ConversionRequest request;
  SetComposer(session.get(), &request);
  FillT13Ns(request, &segments);
  GetConverterMock()->SetStartConversionForRequest(&segments, true);

  command.Clear();
  EXPECT_TRUE(session->ConvertToHalfASCII(&command));
  EXPECT_SINGLE_SEGMENT("ssh", command);
}

TEST_F(SessionTest, KeitaiInput_toggle) {
  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);
  scoped_ptr<Session> session(new Session(engine_.get()));

  InitSessionToPrecomposition(session.get(), *mobile_request_);
  commands::Command command;

  SendKey("1", session.get(), &command);
  // "あ|"
  EXPECT_EQ(kHiraganaA, command.output().preedit().segment(0).value());
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendKey("1", session.get(), &command);
  // "い|"
  EXPECT_EQ("\xE3\x81\x84", command.output().preedit().segment(0).value());
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  SendKey("1", session.get(), &command);
  // "あ|"
  EXPECT_EQ(kHiraganaA, command.output().preedit().segment(0).value());
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendKey("2", session.get(), &command);
  // "あか|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8B",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(2, command.output().preedit().cursor());

  SendKey("2", session.get(), &command);
  // "あき|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(2, command.output().preedit().cursor());

  SendKey("*", session.get(), &command);
  // "あぎ|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8E",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(2, command.output().preedit().cursor());

  SendKey("*", session.get(), &command);
  // "あき|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(2, command.output().preedit().cursor());

  SendKey("3", session.get(), &command);
  // "あきさ|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(3, command.output().preedit().cursor());

  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  // "あきさ|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(3, command.output().preedit().cursor());

  SendKey("3", session.get(), &command);
  // "あきささ|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(4, command.output().preedit().cursor());

  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  // "あきさ|さ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(3, command.output().preedit().cursor());

  SendKey("4", session.get(), &command);
  // "あきさた|さ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95\xE3\x81\x9F\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(4, command.output().preedit().cursor());

  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  // "あきさ|たさ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x95\xE3\x81\x9F\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(3, command.output().preedit().cursor());

  SendKey("*", session.get(), &command);
  // "あきざ|たさ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95",
            command.output().preedit().segment(0).value());
  EXPECT_EQ(3, command.output().preedit().cursor());

  // Test for End key
  SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
  SendKey("6", session.get(), &command);
  SendKey("6", session.get(), &command);
  SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
  SendKey("6", session.get(), &command);
  SendKey("*", session.get(), &command);
  // "あきざたさひば|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0",
      command.output().preedit().segment(0).value());
  EXPECT_EQ(7, command.output().preedit().cursor());

  // Test for Right key
  SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
  SendKey("6", session.get(), &command);
  SendKey("6", session.get(), &command);
  SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
  SendKey("6", session.get(), &command);
  SendKey("*", session.get(), &command);
  // "あきざたさひばひば|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0",
      command.output().preedit().segment(0).value());
  EXPECT_EQ(9, command.output().preedit().cursor());

  // Test for Left key
  SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
  SendKey("6", session.get(), &command);
  SendKey("6", session.get(), &command);
  // "あきざたさひばひばひ|"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2",
      command.output().preedit().segment(0).value());
  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
  SendKey("6", session.get(), &command);
  // "あきざたさひばひばは|ひ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xAF"
      "\xE3\x81\xB2",
      command.output().preedit().segment(0).value());
  SendKey("*", session.get(), &command);
  // "あきざたさひばひばば|ひ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB0"
      "\xE3\x81\xB2",
      command.output().preedit().segment(0).value());
  EXPECT_EQ(10, command.output().preedit().cursor());

  // Test for Home key
  SendSpecialKey(commands::KeyEvent::HOME, session.get(), &command);
  // "|あきざたさひばひばばひ"
  EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F\xE3\x81\x95"
      "\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB0"
      "\xE3\x81\xB2",
      command.output().preedit().segment(0).value());
  SendKey("6", session.get(), &command);
  SendKey("*", session.get(), &command);
  // "ば|あきざたさひばひばばひ"
  EXPECT_EQ("\xE3\x81\xB0\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F"
      "\xE3\x81\x95\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0"
      "\xE3\x81\xB0\xE3\x81\xB2",
      command.output().preedit().segment(0).value());
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
  SendKey("5", session.get(), &command);
  // "ばあきざたさひばひばばひな|"
  EXPECT_EQ("\xE3\x81\xB0\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F"
      "\xE3\x81\x95\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0"
      "\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xAA",
      command.output().preedit().segment(0).value());
  SendKey("*", session.get(), &command);  // no effect
  // "ばあきざたさひばひばばひな|"
  EXPECT_EQ("\xE3\x81\xB0\xE3\x81\x82\xE3\x81\x8D\xE3\x81\x96\xE3\x81\x9F"
      "\xE3\x81\x95\xE3\x81\xB2\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xB0"
      "\xE3\x81\xB0\xE3\x81\xB2\xE3\x81\xAA",
      command.output().preedit().segment(0).value());
  EXPECT_EQ(13, command.output().preedit().cursor());
}

TEST_F(SessionTest, KeitaiInput_flick) {
  config::Config config;
  config.set_session_keymap(config::Config::MSIME);
  config::ConfigHandler::SetConfig(config);
  commands::Command command;

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get(), *mobile_request_);
    // "は"
    InsertCharacterCodeAndString('6', "\xE3\x81\xAF", session.get(), &command);
    // "し"
    InsertCharacterCodeAndString('3', "\xE3\x81\x97", session.get(), &command);
    SendKey("*", session.get(), &command);
    // "ょ"
    InsertCharacterCodeAndString('3', "\xE3\x82\x87", session.get(), &command);
    // "う"
    InsertCharacterCodeAndString('1', "\xE3\x81\x86", session.get(), &command);
    // "はじょう"
    EXPECT_EQ("\xE3\x81\xAF\xE3\x81\x98\xE3\x82\x87\xE3\x81\x86",
        command.output().preedit().segment(0).value());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get(), *mobile_request_);

    SendKey("6", session.get(), &command);
    SendKey("3", session.get(), &command);
    SendKey("3", session.get(), &command);
    SendKey("*", session.get(), &command);
    // "ょ"
    InsertCharacterCodeAndString('3', "\xE3\x82\x87", session.get(), &command);
    // "う"
    InsertCharacterCodeAndString('1', "\xE3\x81\x86", session.get(), &command);
    // "はじょう"
    EXPECT_EQ("\xE3\x81\xAF\xE3\x81\x98\xE3\x82\x87\xE3\x81\x86",
        command.output().preedit().segment(0).value());
  }

  {
    scoped_ptr<Session> session(new Session(engine_.get()));
    InitSessionToPrecomposition(session.get(), *mobile_request_);

    SendKey("1", session.get(), &command);
    SendKey("2", session.get(), &command);
    SendKey("3", session.get(), &command);
    SendKey("3", session.get(), &command);
    // "あかし"
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8B\xE3\x81\x97",
        command.output().preedit().segment(0).value());
    // "の"
    InsertCharacterCodeAndString('5', "\xE3\x81\xAE", session.get(), &command);
    // "く"
    InsertCharacterCodeAndString('2', "\xE3\x81\x8F", session.get(), &command);
    // "し"
    InsertCharacterCodeAndString('3', "\xE3\x81\x97", session.get(), &command);
    // "あかしのくし"
    EXPECT_EQ("\xE3\x81\x82\xE3\x81\x8B\xE3\x81\x97\xE3\x81\xAE\xE3\x81\x8F\xE3"
        "\x81\x97",
        command.output().preedit().segment(0).value());
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendKey("9", session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    // "ん"
    InsertCharacterCodeAndString('0', "\xE3\x82\x93", session.get(), &command);
    SendSpecialKey(commands::KeyEvent::END, session.get(), &command);
    SendKey("1", session.get(), &command);
    SendKey("1", session.get(), &command);
    SendKey("1", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);
    // "ゆ"
    InsertCharacterCodeAndString('8', "\xE3\x82\x86", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendKey("*", session.get(), &command);
    SendKey("*", session.get(), &command);
    // "あるかしんのくしゅう"
    EXPECT_EQ("\xE3\x81\x82\xE3\x82\x8B\xE3\x81\x8B\xE3\x81\x97\xE3\x82\x93\xE3"
        "\x81\xAE\xE3\x81\x8F\xE3\x81\x97\xE3\x82\x85\xE3\x81\x86",
        command.output().preedit().segment(0).value());
    SendSpecialKey(commands::KeyEvent::HOME, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    // "は"
    InsertCharacterCodeAndString('6', "\xE3\x81\xAF", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendKey("*", session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendSpecialKey(commands::KeyEvent::RIGHT, session.get(), &command);
    SendKey("6", session.get(), &command);
    SendKey("6", session.get(), &command);
    SendKey("6", session.get(), &command);
    // "あるぱかしんのふくしゅう"
    EXPECT_EQ("\xE3\x81\x82\xE3\x82\x8B\xE3\x81\xB1\xE3\x81\x8B\xE3\x81\x97\xE3"
        "\x82\x93\xE3\x81\xAE\xE3\x81\xB5\xE3\x81\x8F\xE3\x81\x97\xE3\x82\x85"
        "\xE3\x81\x86",
        command.output().preedit().segment(0).value());
  }
}

TEST_F(SessionTest, CommitCandidateAt2ndOf3Segments) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  ConversionRequest request;
  SetComposer(session.get(), &request);

  commands::Command command;
  InsertCharacterChars("nekonoshippowonuita", session.get(), &command);

  {  // Segments as conversion result.
    Segments segments;
    Segment *segment;
    Segment::Candidate *candidate;

    segment = segments.add_segment();
    // "ねこの"
    segment->set_key("\xE3\x81\xAD\xE3\x81\x93\xE3\x81\xAE");
    candidate = segment->add_candidate();
    // "猫の"
    candidate->value = "\xE7\x8C\xAB\xE3\x81\xAE";

    segment = segments.add_segment();
    // "しっぽを"
    segment->set_key("\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92");
    candidate = segment->add_candidate();
    // "しっぽを"
    candidate->value = "\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92";

    segment = segments.add_segment();
    // "ぬいた"
    segment->set_key("\xE3\x81\xAC\xE3\x81\x84\xE3\x81\x9F");
    candidate = segment->add_candidate();
    // "抜いた"
    candidate->value = "\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F";

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  command.Clear();
  session->Convert(&command);
  // "[猫の]|しっぽを|抜いた"

  command.Clear();
  session->SegmentFocusRight(&command);
  // "猫の|[しっぽを]|抜いた"

  {  // Segments as result of CommitHeadToFocusedSegments
    Segments segments;
    Segment *segment;
    Segment::Candidate *candidate;

    segment = segments.add_segment();
    // "ぬいた"
    segment->set_key("\xE3\x81\xAC\xE3\x81\x84\xE3\x81\x9F");
    candidate = segment->add_candidate();
    // "抜いた"
    candidate->value = "\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F";

    GetConverterMock()->SetCommitSegments(&segments, true);
  }

  command.Clear();
  command.mutable_input()->mutable_command()->set_id(0);
  ASSERT_TRUE(session->CommitCandidate(&command));
  // "抜いた"
  EXPECT_PREEDIT("\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F", command);
  // "抜いた" "ぬいた"
  EXPECT_SINGLE_SEGMENT_AND_KEY("\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F",
                                "\xE3\x81\xAC\xE3\x81\x84\xE3\x81\x9F",
                                command);
  // "猫のしっぽを"
  EXPECT_RESULT("\xE7\x8C\xAB\xE3\x81\xAE"
                "\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92", command);
}

TEST_F(SessionTest, CommitCandidateAt3rdOf3Segments) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  ConversionRequest request;
  SetComposer(session.get(), &request);

  commands::Command command;
  InsertCharacterChars("nekonoshippowonuita", session.get(), &command);

  {  // Segments as conversion result.
    Segments segments;
    Segment *segment;
    Segment::Candidate *candidate;

    segment = segments.add_segment();
    // "ねこの"
    segment->set_key("\xE3\x81\xAD\xE3\x81\x93\xE3\x81\xAE");
    candidate = segment->add_candidate();
    // "猫の"
    candidate->value = "\xE7\x8C\xAB\xE3\x81\xAE";

    segment = segments.add_segment();
    // "しっぽを"
    segment->set_key("\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92");
    candidate = segment->add_candidate();
    // "しっぽを"
    candidate->value = "\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92";

    segment = segments.add_segment();
    // "ぬいた"
    segment->set_key("\xE3\x81\xAC\xE3\x81\x84\xE3\x81\x9F");
    candidate = segment->add_candidate();
    // "抜いた"
    candidate->value = "\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F";

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
  }

  command.Clear();
  session->Convert(&command);
  // "[猫の]|しっぽを|抜いた"

  command.Clear();
  session->SegmentFocusRight(&command);
  session->SegmentFocusRight(&command);
  // "猫の|しっぽを|[抜いた]"

  {  // Segments as result of CommitHeadToFocusedSegments
    Segments segments;
    GetConverterMock()->SetCommitSegments(&segments, true);
  }

  command.Clear();
  command.mutable_input()->mutable_command()->set_id(0);
  ASSERT_TRUE(session->CommitCandidate(&command));
  EXPECT_FALSE(command.output().has_preedit());
  // "猫のしっぽを抜いた"
  EXPECT_RESULT("\xE7\x8C\xAB\xE3\x81\xAE"
                "\xE3\x81\x97\xE3\x81\xA3\xE3\x81\xBD\xE3\x82\x92"
                "\xE6\x8A\x9C\xE3\x81\x84\xE3\x81\x9F" , command);
}

TEST_F(SessionTest, CommitCandidate_suggestion) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get(), *mobile_request_);

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    AddCandidate("MOCHA", "MOCHA", segment);
    AddCandidate("MOZUKU", "MOZUKU", segment);
  }

  commands::Command command;
  SendKey("M", session.get(), &command);
  command.Clear();
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  EXPECT_EQ(2, command.output().candidates().candidate_size());
  EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

  GetConverterMock()->SetFinishConversion(
      scoped_ptr<Segments>(new Segments).get(), true);
  SetSendCommandCommand(commands::SessionCommand::SUBMIT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(1);
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_RESULT_AND_KEY("MOZUKU", "MOZUKU", command);
  EXPECT_FALSE(command.output().has_preedit());
  // Zero query suggestion fills the candidates.
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_EQ(0, command.output().preedit().cursor());
}

bool FindCandidateID(const commands::Candidates &candidates,
                      const string &value, int *id) {
  CHECK(id);
  for (size_t i = 0; i < candidates.candidate_size(); ++i) {
    const commands::Candidates::Candidate &candidate =
        candidates.candidate(i);
    if (candidate.value() == value) {
      *id = candidate.id();
      return true;
    }
  }
  return false;
}

TEST_F(SessionTest, CommitCandidate_T13N) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get(), *mobile_request_);

  {
    Segments segments;
    segments.set_request_type(Segments::SUGGESTION);

    Segment *segment;
    segment = segments.add_segment();
    segment->set_key("tok");
    AddCandidate("tok", "tok", segment);
    AddMetaCandidate("tok", "tok", segment);
    AddMetaCandidate("tok", "TOK", segment);
    AddMetaCandidate("tok", "Tok", segment);
    EXPECT_EQ("tok", segment->candidate(-1).value);
    EXPECT_EQ("TOK", segment->candidate(-2).value);
    EXPECT_EQ("Tok", segment->candidate(-3).value);

    GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
  }

  {
    Segments segments;
    segments.set_request_type(Segments::PREDICTION);

    Segment *segment;
    segment = segments.add_segment();
    segment->set_key("tok");
    AddCandidate("tok", "tok", segment);
    AddMetaCandidate("tok", "tok", segment);
    AddMetaCandidate("tok", "TOK", segment);
    AddMetaCandidate("tok", "Tok", segment);
    EXPECT_EQ("tok", segment->candidate(-1).value);
    EXPECT_EQ("TOK", segment->candidate(-2).value);
    EXPECT_EQ("Tok", segment->candidate(-3).value);
    GetConverterMock()->SetStartPredictionForRequest(&segments, true);
  }

  commands::Command command;
  SendKey("k", session.get(), &command);
  ASSERT_TRUE(command.output().has_candidates());
  int id = 0;
#if defined(OS_WIN) || defined(OS_MACOSX)
  // meta candidates are in cascading window
  EXPECT_FALSE(FindCandidateID(command.output().candidates(), "TOK", &id));
#else
  EXPECT_TRUE(FindCandidateID(command.output().candidates(), "TOK", &id));
  GetConverterMock()->SetFinishConversion(
      scoped_ptr<Segments>(new Segments).get(), true);
  SetSendCommandCommand(commands::SessionCommand::SUBMIT_CANDIDATE, &command);
  command.mutable_input()->mutable_command()->set_id(id);
  session->SendCommand(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_RESULT("TOK", command);
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_EQ(0, command.output().preedit().cursor());
#endif
}

TEST_F(SessionTest, RequestConvertReverse) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  EXPECT_TRUE(session->RequestConvertReverse(&command));
  EXPECT_FALSE(command.output().has_result());
  EXPECT_FALSE(command.output().has_deletion_range());
  EXPECT_TRUE(command.output().has_callback());
  EXPECT_TRUE(command.output().callback().has_session_command());
  EXPECT_EQ(commands::SessionCommand::CONVERT_REVERSE,
            command.output().callback().session_command().type());
}

TEST_F(SessionTest, ConvertReverse) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "阿伊宇江於"
  const char kKanjiAiueo[] =
      "\xe9\x98\xbf\xe4\xbc\x8a\xe5\xae\x87\xe6\xb1\x9f\xe6\x96\xbc";
  commands::Command command;
  SetupCommandForReverseConversion(kKanjiAiueo, command.mutable_input());
  SetupMockForReverseConversion(kKanjiAiueo, kAiueo);

  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kKanjiAiueo,
            command.output().preedit().segment(0).value());
  EXPECT_EQ(kKanjiAiueo,
            command.output().all_candidate_words().candidates(0).value());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_GT(command.output().candidates().candidate_size(), 0);
}

TEST_F(SessionTest, EscapeFromConvertReverse) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "阿伊宇江於"
  const char kKanjiAiueo[] =
      "\xe9\x98\xbf\xe4\xbc\x8a\xe5\xae\x87\xe6\xb1\x9f\xe6\x96\xbc";

  commands::Command command;
  SetupCommandForReverseConversion(kKanjiAiueo, command.mutable_input());
  SetupMockForReverseConversion(kKanjiAiueo, kAiueo);

  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kKanjiAiueo, GetComposition(command));

  SendKey("ESC", session.get(), &command);

  // KANJI should be converted into HIRAGANA in pre-edit state.
  EXPECT_SINGLE_SEGMENT(kAiueo, command);

  SendKey("ESC", session.get(), &command);

  // Fixed KANJI should be output
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_RESULT(kKanjiAiueo, command);
}

TEST_F(SessionTest, SecondEscapeFromConvertReverse) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "阿伊宇江於"
  const char kKanjiAiueo[] =
      "\xe9\x98\xbf\xe4\xbc\x8a\xe5\xae\x87\xe6\xb1\x9f\xe6\x96\xbc";
  commands::Command command;
  SetupCommandForReverseConversion(kKanjiAiueo, command.mutable_input());
  SetupMockForReverseConversion(kKanjiAiueo, kAiueo);

  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kKanjiAiueo, GetComposition(command));

  SendKey("ESC", session.get(), &command);
  SendKey("ESC", session.get(), &command);

  EXPECT_FALSE(command.output().has_preedit());
  // When a reverse conversion is canceled, the converter sets the
  // original text into |command.output().result().key()|.
  EXPECT_RESULT_AND_KEY(kKanjiAiueo, kKanjiAiueo, command);

  SendKey("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  SendKey("ESC", session.get(), &command);
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, SecondEscapeFromConvertReverse_Issue5687022) {
  // This is a unittest against http://b/5687022
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  const char kInput[] = "abcde";
  const char kReading[] = "abcde";

  commands::Command command;
  SetupCommandForReverseConversion(kInput, command.mutable_input());
  SetupMockForReverseConversion(kInput, kReading);

  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kInput, GetComposition(command));

  SendKey("ESC", session.get(), &command);
  SendKey("ESC", session.get(), &command);

  EXPECT_FALSE(command.output().has_preedit());
  // When a reverse conversion is canceled, the converter sets the
  // original text into |result().key()|.
  EXPECT_RESULT_AND_KEY(kInput, kInput, command);
}

TEST_F(SessionTest, SecondEscapeFromConvertReverseKeepsOriginalText) {
  // Second escape from ConvertReverse should restore the original text
  // without any text normalization even if the input text contains any
  // special characters which Mozc usually do normalization.

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "ゔ"
  const char kInput[] = "\xE3\x82\x94";

  commands::Command command;
  SetupCommandForReverseConversion(kInput, command.mutable_input());
  SetupMockForReverseConversion(kInput, kInput);

  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kInput, GetComposition(command));

  SendKey("ESC", session.get(), &command);
  SendKey("ESC", session.get(), &command);

  EXPECT_FALSE(command.output().has_preedit());

  // When a reverse conversion is canceled, the converter sets the
  // original text into |result().key()|.
  EXPECT_RESULT_AND_KEY(kInput, kInput, command);
}

TEST_F(SessionTest, EscapeFromCompositionAfterConvertReverse) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "阿伊宇江於"
  const char kKanjiAiueo[] =
      "\xe9\x98\xbf\xe4\xbc\x8a\xe5\xae\x87\xe6\xb1\x9f\xe6\x96\xbc";

  commands::Command command;
  SetupCommandForReverseConversion(kKanjiAiueo, command.mutable_input());
  SetupMockForReverseConversion(kKanjiAiueo, kAiueo);

  // Conversion Reverse
  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kKanjiAiueo, GetComposition(command));

  session->Commit(&command);

  EXPECT_RESULT(kKanjiAiueo, command);

  // Escape in composition state
  SendKey("a", session.get(), &command);
  // "あ"
  EXPECT_EQ(kHiraganaA, GetComposition(command));

  SendKey("ESC", session.get(), &command);
  EXPECT_FALSE(command.output().has_preedit());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, ConvertReverseFromOffState) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  // "阿伊宇江於"
  const string kanji_aiueo =
      "\xe9\x98\xbf\xe4\xbc\x8a\xe5\xae\x87\xe6\xb1\x9f\xe6\x96\xbc";

  // IMEOff
  commands::Command command;
  SendSpecialKey(commands::KeyEvent::OFF, session.get(), &command);

  SetupCommandForReverseConversion(kanji_aiueo, command.mutable_input());
  SetupMockForReverseConversion(kanji_aiueo, kAiueo);
  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
}

TEST_F(SessionTest, DCHECKFailureAfterConvertReverse) {
  // This is a unittest against http://b/5145295.
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  SetupCommandForReverseConversion(kAiueo, command.mutable_input());
  SetupMockForReverseConversion(kAiueo, kAiueo);
  EXPECT_TRUE(session->SendCommand(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(kAiueo, command.output().preedit().segment(0).value());
  EXPECT_EQ(kAiueo,
      command.output().all_candidate_words().candidates(0).value());
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_GT(command.output().candidates().candidate_size(), 0);

  SendKey("ESC", session.get(), &command);
  SendKey("a", session.get(), &command);
  // "あいうえおあ"
  EXPECT_EQ(string(kAiueo) + kHiraganaA,
            command.output().preedit().segment(0).value());
  EXPECT_FALSE(command.output().has_result());
}

TEST_F(SessionTest, LaunchTool) {
  scoped_ptr<Session> session(new Session(engine_.get()));

  {
    commands::Command command;
    EXPECT_TRUE(session->LaunchConfigDialog(&command));
    EXPECT_EQ(commands::Output::CONFIG_DIALOG,
              command.output().launch_tool_mode());
    EXPECT_TRUE(command.output().consumed());
  }

  {
    commands::Command command;
    EXPECT_TRUE(session->LaunchDictionaryTool(&command));
    EXPECT_EQ(commands::Output::DICTIONARY_TOOL,
              command.output().launch_tool_mode());
    EXPECT_TRUE(command.output().consumed());
  }

  {
    commands::Command command;
    EXPECT_TRUE(session->LaunchWordRegisterDialog(&command));
    EXPECT_EQ(commands::Output::WORD_REGISTER_DIALOG,
              command.output().launch_tool_mode());
    EXPECT_TRUE(command.output().consumed());
  }
}

TEST_F(SessionTest, NotZeroQuerySuggest) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // Disable zero query suggest.
  commands::Request request;
  request.set_zero_query_suggestion(false);
  session->SetRequest(&request);

  // Type "google".
  commands::Command command;
  InsertCharacterChars("google", session.get(), &command);
  EXPECT_EQ("google", GetComposition(command));

  // Set up a mock suggestion result.
  Segments segments;
  segments.set_request_type(Segments::SUGGESTION);
  Segment *segment;
  segment = segments.add_segment();
  segment->set_key("");
  segment->add_candidate()->value = "search";
  segment->add_candidate()->value = "input";
  GetConverterMock()->SetStartSuggestionForRequest(&segments, true);

  // Commit composition and zero query suggest should not be invoked.
  command.Clear();
  session->Commit(&command);
  EXPECT_EQ("google", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_FALSE(command.output().has_candidates());

  const ImeContext &context = session->context();
  EXPECT_EQ(ImeContext::PRECOMPOSITION, context.state());
}

TEST_F(SessionTest, ZeroQuerySuggest) {
  {  // Commit
    Session session(engine_.get());
    commands::Request request;
    SetupZeroQuerySuggestionReady(true, &session, &request);

    commands::Command command;
    session.Commit(&command);
    EXPECT_EQ("GOOGLE", command.output().result().value());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("search", command.output().candidates().candidate(0).value());
    EXPECT_EQ("input", command.output().candidates().candidate(1).value());
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // CommitSegment
    Session session(engine_.get());
    commands::Request request;
    SetupZeroQuerySuggestionReady(true, &session, &request);

    commands::Command command;
    session.CommitSegment(&command);
    EXPECT_EQ("GOOGLE", command.output().result().value());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("search", command.output().candidates().candidate(0).value());
    EXPECT_EQ("input", command.output().candidates().candidate(1).value());
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // CommitCandidate
    Session session(engine_.get());
    commands::Request request;
    SetupZeroQuerySuggestionReady(true, &session, &request);

    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::SUBMIT_CANDIDATE, &command);
    command.mutable_input()->mutable_command()->set_id(0);
    session.SendCommand(&command);

    EXPECT_EQ("GOOGLE", command.output().result().value());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("search", command.output().candidates().candidate(0).value());
    EXPECT_EQ("input", command.output().candidates().candidate(1).value());
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // CommitFirstSuggestion
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Enable zero query suggest.
    commands::Request request;
    request.set_zero_query_suggestion(true);
    session.SetRequest(&request);

    // Type "g".
    commands::Command command;
    InsertCharacterChars("g", &session, &command);

    {
      // Set up a mock conversion result.
      Segments segments;
      segments.set_request_type(Segments::SUGGESTION);
      Segment *segment;
      segment = segments.add_segment();
      segment->set_key("");
      segment->add_candidate()->value = "google";
      GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
    }

    command.Clear();
    InsertCharacterChars("o", &session, &command);

    {
      // Set up a mock suggestion result.
      Segments segments;
      segments.set_request_type(Segments::SUGGESTION);
      Segment *segment;
      segment = segments.add_segment();
      segment->set_key("");
      segment->add_candidate()->value = "search";
      segment->add_candidate()->value = "input";
      GetConverterMock()->SetStartSuggestionForRequest(&segments, true);
    }

    command.Clear();
    Segments empty_segments;
    GetConverterMock()->SetFinishConversion(&empty_segments, true);
    session.CommitFirstSuggestion(&command);
    EXPECT_EQ("google", command.output().result().value());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("search", command.output().candidates().candidate(0).value());
    EXPECT_EQ("input", command.output().candidates().candidate(1).value());
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }
}

TEST_F(SessionTest, CommandsAfterZeroQuerySuggest) {
  {  // Cancel command should close the candidate window.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    command.Clear();
    session.EditCancel(&command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // PredictAndConvert should select the first candidate.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    command.Clear();
    session.PredictAndConvert(&command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result());
    // "search" is the first suggest candidate.
    EXPECT_PREEDIT("search", command);
    EXPECT_EQ(ImeContext::CONVERSION, session.context().state());
  }

  {  // CommitFirstSuggestion should insert the first candidate.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    command.Clear();
    // FinishConversion is expected to return empty Segments.
    GetConverterMock()->SetFinishConversion(
        scoped_ptr<Segments>(new Segments).get(), true);
    session.CommitFirstSuggestion(&command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_EQ("", GetComposition(command));
    // "search" is the first suggest candidate.
    EXPECT_RESULT("search", command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // Space should be inserted directly.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    SendKey("Space", &session, &command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_EQ("", GetComposition(command));
    // "　" (full-width space)
    EXPECT_RESULT(kFullWidthSpace, command);
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // 'a' should be inserted in the composition.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());

    SendKey("a", &session, &command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ(commands::HIRAGANA, command.output().mode());
    // "あ"
    EXPECT_PREEDIT(kHiraganaA, command);
    EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());
  }

  {  // Enter should be inserted directly.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    SendKey("Enter", &session, &command);
    EXPECT_FALSE(command.output().consumed());
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // Right should be inserted directly.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    SendKey("Right", &session, &command);
    EXPECT_FALSE(command.output().consumed());
    EXPECT_FALSE(command.output().has_preedit());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  }

  {  // SelectCnadidate command should work with zero query suggestion.
    Session session(engine_.get());
    commands::Request request;
    commands::Command command;
    SetupZeroQuerySuggestion(&session, &request, &command);

    // Send SELECT_CANDIDATE command.
    const int first_id = command.output().candidates().candidate(0).id();
    SetSendCommandCommand(commands::SessionCommand::SELECT_CANDIDATE, &command);
    command.mutable_input()->mutable_command()->set_id(first_id);
    EXPECT_TRUE(session.SendCommand(&command));

    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result());
    // "search" is the first suggest candidate.
    EXPECT_PREEDIT("search", command);
    EXPECT_EQ(ImeContext::CONVERSION, session.context().state());
  }
}

TEST_F(SessionTest, Issue4437420) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);
  commands::Command command;
  commands::Request request;
  // Creates overriding config.
  config::Config overriding_config;
  overriding_config.set_session_keymap(config::Config::MOBILE);
  // Change to 12keys-halfascii mode.
  SwitchInputMode(commands::HALF_ASCII, &session);

  command.Clear();
  request.set_special_romanji_table(
      commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII);
  session.SetRequest(&request);
  scoped_ptr<composer::Table> table(new composer::Table());
  table->InitializeWithRequestAndConfig(
      request, config::ConfigHandler::GetConfig());
  session.SetTable(table.get());
  // Type "2*" to produce "A".
  SetSendKeyCommand("2", &command);
  command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
  session.SendKey(&command);
  SetSendKeyCommand("*", &command);
  command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
  session.SendKey(&command);
  EXPECT_EQ("A", GetComposition(command));

  // Change to 12keys-halfascii mode.
  SwitchInputMode(commands::HALF_ASCII, &session);

  command.Clear();
  request.set_special_romanji_table(
      commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII);
  session.SetRequest(&request);
  table.reset(new composer::Table());
  table->InitializeWithRequestAndConfig(
      request, config::ConfigHandler::GetConfig());
  session.SetTable(table.get());
  // Type "2" to produce "Aa".
  SetSendKeyCommand("2", &command);
  command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
  session.SendKey(&command);
  EXPECT_EQ("Aa", GetComposition(command));
  command.Clear();
}

// If undo context is empty, key event for UNDO should be echoed back. b/5553298
TEST_F(SessionTest, Issue5553298) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  // Undo requires capability DELETE_PRECEDING_TEXT.
  commands::Capability capability;
  capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
  session.set_client_capability(capability);

  commands::Command command;
  session.ResetContext(&command);

  SetSendKeyCommand("Ctrl Backspace", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MSIME);
  session.TestSendKey(&command);
  EXPECT_FALSE(command.output().consumed());

  SetSendKeyCommand("Ctrl Backspace", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MSIME);
  session.SendKey(&command);
  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, UndoKeyAction) {
  commands::Command command;
  commands::Request request;
  // Creates overriding config.
  config::Config overriding_config;
  overriding_config.set_session_keymap(config::Config::MOBILE);
  // Test in half width ascii mode.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Change to 12keys-halfascii mode.
    SwitchInputMode(commands::HALF_ASCII, &session);

    command.Clear();
    request.set_special_romanji_table(
        commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII);
    session.SetRequest(&request);
    composer::Table table;
    table.InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session.SetTable(&table);

    // Type "2" to produce "a".
    SetSendKeyCommand("2", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    EXPECT_EQ("a", GetComposition(command));

    // Type "2" again to produce "b".
    SetSendKeyCommand("2", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    EXPECT_EQ("b", GetComposition(command));

    // Push UNDO key to reproduce "a".
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    EXPECT_EQ("a", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());

    // Push UNDO key again to produce "2".
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    EXPECT_EQ("2", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
  }

  // Test in Hiaragana-mode.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Change to 12keys-Hiragana mode.
    SwitchInputMode(commands::HIRAGANA, &session);

    command.Clear();
    request.set_special_romanji_table(
        commands::Request::TWELVE_KEYS_TO_HIRAGANA);
    session.SetRequest(&request);
    composer::Table table;
    table.InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session.SetTable(&table);
    // Type "33{<}{<}" to produce "さ"->"し"->"さ"->"そ".
    SetSendKeyCommand("3", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "さ"
    EXPECT_EQ("\xE3\x81\x95", GetComposition(command));

    SetSendKeyCommand("3", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "し"
    EXPECT_EQ("\xE3\x81\x97", GetComposition(command));

    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    // "さ"
    EXPECT_EQ("\xE3\x81\x95", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();

    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    // "そ"
    EXPECT_EQ("\xE3\x81\x9D", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
  }

  // Test to do nothing for voiced sounds.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Change to 12keys-Hiragana mode.
    SwitchInputMode(commands::HIRAGANA, &session);

    command.Clear();
    request.set_special_romanji_table(
        commands::Request::TWELVE_KEYS_TO_HIRAGANA);
    session.SetRequest(&request);
    composer::Table table;
    table.InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session.SetTable(&table);
    // Type "3*{<}*{<}", and composition should change
    // "さ"->"ざ"->(No change)->"さ"->(No change).
    SetSendKeyCommand("3", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "さ"
    EXPECT_EQ("\xE3\x81\x95", GetComposition(command));

    SetSendKeyCommand("*", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "ざ"
    EXPECT_EQ("\xE3\x81\x96", GetComposition(command));

    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    // "ざ"
    EXPECT_EQ("\xE3\x81\x96", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());


    SetSendKeyCommand("*", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "さ"
    EXPECT_EQ("\xE3\x81\x95", GetComposition(command));
    command.Clear();

    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    // "さ"
    EXPECT_EQ("\xE3\x81\x95", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
  }

  // Test to make nothing newly in preedit for empty composition.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Change to 12keys-Hiragana mode.
    SwitchInputMode(commands::HIRAGANA, &session);

    command.Clear();
    request.set_special_romanji_table(
        commands::Request::TWELVE_KEYS_TO_HIRAGANA);
    session.SetRequest(&request);
    composer::Table table;
    table.InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session.SetTable(&table);
    // Type "{<}" and do nothing
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);

    EXPECT_FALSE(command.output().has_preedit());

    command.Clear();
  }

  // Test of acting as UNDO key. Almost same as the first section in Undo test.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    commands::Capability capability;
    capability.set_text_deletion(commands::Capability::DELETE_PRECEDING_TEXT);
    session.set_client_capability(capability);

    Segments segments;
    InsertCharacterChars("aiueo", &session, &command);
    ConversionRequest request;
    SetComposer(&session, &request);
    SetAiueo(&segments);
    Segment::Candidate *candidate;
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "aiueo";
    candidate = segments.mutable_segment(0)->add_candidate();
    candidate->value = "AIUEO";

    GetConverterMock()->SetStartConversionForRequest(&segments, true);
    command.Clear();
    session.Convert(&command);
    EXPECT_FALSE(command.output().has_result());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);

    GetConverterMock()->SetCommitSegmentValue(&segments, true);
    command.Clear();
    session.Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あいうえお"
    EXPECT_RESULT(kAiueo, command);

    command.Clear();
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_TRUE(command.output().has_deletion_range());
    EXPECT_EQ(-5, command.output().deletion_range().offset());
    EXPECT_EQ(5, command.output().deletion_range().length());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);
    EXPECT_TRUE(command.output().consumed());

    // Undo twice - do nothing and keep the previous status.
    command.Clear();
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    session.SendCommand(&command);
    EXPECT_FALSE(command.output().has_result());
    EXPECT_FALSE(command.output().has_deletion_range());
    // "あいうえお"
    EXPECT_PREEDIT(kAiueo, command);
    EXPECT_TRUE(command.output().consumed());
  }

  // Do not UNDO even if UNDO stack is not empty if it is in COMPOSITE state.
  {
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    // Change to 12keys-Hiragana mode.
    SwitchInputMode(commands::HIRAGANA, &session);

    command.Clear();
    request.set_special_romanji_table(
        commands::Request::TWELVE_KEYS_TO_HIRAGANA);
    session.SetRequest(&request);
    composer::Table table;
    table.InitializeWithRequestAndConfig(
        request, config::ConfigHandler::GetConfig());
    session.SetTable(&table);

    // commit "あ" to push UNDO stack
    SetSendKeyCommand("1", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "あ"
    EXPECT_EQ(kHiraganaA, GetComposition(command));
    command.Clear();

    session.Commit(&command);
    EXPECT_FALSE(command.output().has_preedit());
    // "あ"
    EXPECT_RESULT(kHiraganaA, command);

    // Produce "か" in composition.
    SetSendKeyCommand("2", &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendKey(&command);
    // "か"
    EXPECT_EQ("\xE3\x81\x8B", GetComposition(command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();

    // Send UNDO_OR_REWIND key, then get "こ" in composition
    SetSendCommandCommand(commands::SessionCommand::UNDO_OR_REWIND, &command);
    command.mutable_input()->mutable_config()->CopyFrom(overriding_config);
    session.SendCommand(&command);
    // "こ"
    EXPECT_PREEDIT("\xE3\x81\x93", command);
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
  }
}

TEST_F(SessionTest, TemporaryKeyMapChange) {
  config::Config config;
  config::ConfigHandler::GetDefaultConfig(&config);
  config.set_session_keymap(config::Config::ATOK);
  config::ConfigHandler::SetConfig(config);

  // Session created with keymap ATOK
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);
  EXPECT_EQ(config::Config::ATOK, session.context().keymap());

  // TestSendKey with keymap MOBLE
  commands::Command command;
  SetSendKeyCommand("G", &command);
  command.mutable_input()->mutable_config()->set_session_keymap(
      config::Config::MOBILE);
  session.TestSendKey(&command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(config::Config::MOBILE, session.context().keymap());

  // TestSendKey without keymap
  TestSendKey("G", &session, &command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(config::Config::ATOK, session.context().keymap());
}

TEST_F(SessionTest, MoveCursor) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;

  InsertCharacterChars("MOZUKU", session.get(), &command);
  EXPECT_EQ(6, command.output().preedit().cursor());
  session->MoveCursorLeft(&command);
  EXPECT_EQ(5, command.output().preedit().cursor());
  command.mutable_input()->mutable_command()->set_cursor_position(3);
  session->MoveCursorTo(&command);
  EXPECT_EQ(3, command.output().preedit().cursor());
  session->MoveCursorRight(&command);
  EXPECT_EQ(4, command.output().preedit().cursor());
}

TEST_F(SessionTest, MoveCursorRightWithCommit) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(
      commands::Request::QWERTY_MOBILE_TO_HALFWIDTHASCII);
  request.set_crossing_edge_behavior(
      commands::Request::COMMIT_WITHOUT_CONSUMING);
  InitSessionToPrecomposition(session.get(), request);
  commands::Command command;

  InsertCharacterChars("MOZC", session.get(), &command);
  EXPECT_EQ(4, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(3, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorRight(&command);
  EXPECT_EQ(4, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorRight(&command);
  EXPECT_FALSE(command.output().consumed());
  ASSERT_TRUE(command.output().has_result());
  EXPECT_EQ(commands::Result_ResultType_STRING,
            command.output().result().type());
  EXPECT_EQ("MOZC", command.output().result().value());
  EXPECT_EQ(0, command.output().result().cursor_offset());
}

TEST_F(SessionTest, MoveCursorLeftWithCommit) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(
      commands::Request::QWERTY_MOBILE_TO_HALFWIDTHASCII);
  request.set_crossing_edge_behavior(
      commands::Request::COMMIT_WITHOUT_CONSUMING);
  InitSessionToPrecomposition(session.get(), request);
  commands::Command command;

  InsertCharacterChars("MOZC", session.get(), &command);
  EXPECT_EQ(4, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(3, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(2, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(1, command.output().preedit().cursor());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(0, command.output().preedit().cursor());
  command.Clear();

  session->MoveCursorLeft(&command);
  EXPECT_FALSE(command.output().consumed());
  ASSERT_TRUE(command.output().has_result());
  EXPECT_EQ(commands::Result_ResultType_STRING,
            command.output().result().type());
  EXPECT_EQ("MOZC", command.output().result().value());
  EXPECT_EQ(-4, command.output().result().cursor_offset());
}

TEST_F(SessionTest, CommitHead) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  composer::Table table;
  // "も"
  table.AddRule("mo", "\xe3\x82\x82", "");
  // "ず"
  table.AddRule("zu", "\xe3\x81\x9a", "");

  session->get_internal_composer_only_for_unittest()->SetTable(&table);

  InitSessionToPrecomposition(session.get());
  commands::Command command;

  InsertCharacterChars("moz", session.get(), &command);
  // 'もｚ'
  EXPECT_EQ("\xe3\x82\x82\xef\xbd\x9a", GetComposition(command));
  command.Clear();
  session->CommitHead(1, &command);
  EXPECT_EQ(commands::Result_ResultType_STRING,
            command.output().result().type());
  EXPECT_EQ("\xe3\x82\x82", command.output().result().value());  // 'も'
  EXPECT_EQ("\xef\xbd\x9a", GetComposition(command));            // 'ｚ'
  InsertCharacterChars("u", session.get(), &command);
  // 'ず'
  EXPECT_EQ("\xe3\x81\x9a", GetComposition(command));
}

TEST_F(SessionTest, PasswordWithToggleAlpabetInput) {
  scoped_ptr<Session> session(new Session(engine_.get()));

  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(
      commands::Request::TWELVE_KEYS_TO_HALFWIDTHASCII);

  InitSessionToPrecomposition(session.get(), request);

  // Change to 12keys-halfascii mode.
  SwitchInputFieldType(commands::Context::PASSWORD, session.get());
  SwitchInputMode(commands::HALF_ASCII, session.get());

  commands::Command command;
  SendKey("2", session.get(), &command);
  EXPECT_EQ("a", GetComposition(command));
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendKey("2", session.get(), &command);
  EXPECT_EQ("b", GetComposition(command));
  EXPECT_EQ(1, command.output().preedit().cursor());

  // cursor key commits the preedit.
  SendKey("right", session.get(), &command);
  // "b"
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("b", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_EQ(0, command.output().preedit().cursor());

  SendKey("2", session.get(), &command);
  // "b[a]"
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  EXPECT_EQ("a", GetComposition(command));
  EXPECT_EQ(1, command.output().preedit().cursor());

  SendKey("4", session.get(), &command);
  // ba[g]
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("a", command.output().result().value());
  EXPECT_EQ("g", GetComposition(command));
  EXPECT_EQ(1, command.output().preedit().cursor());

  // cursor key commits the preedit.
  SendKey("left", session.get(), &command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("g", command.output().result().value());
  EXPECT_EQ(0, command.output().preedit().segment_size());
  EXPECT_EQ(0, command.output().preedit().cursor());
}

TEST_F(SessionTest, SwitchInputFieldType) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  // initial state is NORMAL
  EXPECT_EQ(commands::Context::NORMAL,
            session->context().composer().GetInputFieldType());

  {
    SCOPED_TRACE("Switch input field type to PASSWORD");
    SwitchInputFieldType(commands::Context::PASSWORD, session.get());
  }
  {
    SCOPED_TRACE("Switch input field type to NORMAL");
    SwitchInputFieldType(commands::Context::NORMAL, session.get());
  }
}

TEST_F(SessionTest, CursorKeysInPasswordMode) {
  scoped_ptr<Session> session(new Session(engine_.get()));

  commands::Request request;
  request.CopyFrom(*mobile_request_);
  request.set_special_romanji_table(commands::Request::DEFAULT_TABLE);
  session->SetRequest(&request);

  InitSessionToPrecomposition(session.get(), request);

  SwitchInputFieldType(commands::Context::PASSWORD, session.get());
  SwitchInputMode(commands::HALF_ASCII, session.get());

  commands::Command command;
  // cursor key commits the preedit without moving system cursor.
  SendKey("m", session.get(), &command);
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  command.Clear();
  session->MoveCursorLeft(&command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("m", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  VLOG(0) << command.DebugString();
  EXPECT_EQ(0, command.output().preedit().cursor());
  EXPECT_TRUE(command.output().consumed());

  SendKey("o", session.get(), &command);
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  command.Clear();
  session->MoveCursorRight(&command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("o", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_EQ(0, command.output().preedit().cursor());
  EXPECT_TRUE(command.output().consumed());

  SendKey("z", session.get(), &command);
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  SetSendCommandCommand(commands::SessionCommand::MOVE_CURSOR, &command);
  command.mutable_input()->mutable_command()->set_cursor_position(3);
  session->MoveCursorTo(&command);
  EXPECT_EQ("z", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_EQ(0, command.output().preedit().cursor());
  EXPECT_TRUE(command.output().consumed());
}

TEST_F(SessionTest, BackKeyCommitsPreeditInPasswordMode) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  commands::Request request;

  request.set_zero_query_suggestion(false);
  request.set_combine_all_segments(true);
  request.set_special_romanji_table(commands::Request::DEFAULT_TABLE);
  session->SetRequest(&request);

  composer::Table table;
  table.InitializeWithRequestAndConfig(
      request, config::ConfigHandler::GetConfig());
  session->SetTable(&table);

  SwitchInputFieldType(commands::Context::PASSWORD, session.get());
  SwitchInputMode(commands::HALF_ASCII, session.get());

  SendKey("m", session.get(), &command);
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  EXPECT_EQ("m", GetComposition(command));
  SendKey("esc", session.get(), &command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("m", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_FALSE(command.output().consumed());

  SendKey("o", session.get(), &command);
  SendKey("z", session.get(), &command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("o", command.output().result().value());
  EXPECT_EQ("z", GetComposition(command));
  SendKey("esc", session.get(), &command);
  EXPECT_EQ(commands::Result::STRING, command.output().result().type());
  EXPECT_EQ("z", command.output().result().value());
  EXPECT_EQ("", GetComposition(command));
  EXPECT_FALSE(command.output().consumed());

  // in normal mode, preedit is cleared without commit.
  SwitchInputFieldType(commands::Context::NORMAL, session.get());

  SendKey("m", session.get(), &command);
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  EXPECT_EQ("m", GetComposition(command));
  SendKey("esc", session.get(), &command);
  EXPECT_TRUE(command.output().consumed());
  EXPECT_EQ(commands::Result::NONE, command.output().result().type());
  EXPECT_FALSE(command.output().has_preedit());
}

TEST_F(SessionTest, EditCancel) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  {  // Cancel of Suggestion
    commands::Command command;
    SendKey("M", &session, &command);

    GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
    SendKey("O", &session, &command);
    ASSERT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

    command.Clear();
    session.EditCancel(&command);
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
  }

  {  // Cancel of Reverse conversion
    commands::Command command;

    // "[MO]" is a converted string like Kanji.
    // "MO" is an input string like Hiragana.
    SetupCommandForReverseConversion("[MO]", command.mutable_input());
    SetupMockForReverseConversion("[MO]", "MO");
    EXPECT_TRUE(session.SendCommand(&command));

    command.Clear();
    GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
    session.ConvertCancel(&command);
    ASSERT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

    command.Clear();
    session.EditCancel(&command);
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    // test case against b/5566728
    EXPECT_RESULT("[MO]", command);
  }
}

TEST_F(SessionTest, ImeOff) {
  scoped_ptr<MockConverterEngineForReset> engine(
      new MockConverterEngineForReset);
  ConverterMockForReset *convertermock = engine->mutable_converter_mock();

  convertermock->Reset();
  scoped_ptr<Session> session(new Session(engine.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  session->IMEOff(&command);

  EXPECT_TRUE(convertermock->reset_conversion_called());
}

TEST_F(SessionTest, EditCancelAndIMEOff) {
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\thankaku/zenkaku\tCancelAndIMEOff\n"
        "Composition\thankaku/zenkaku\tCancelAndIMEOff\n"
        "Conversion\thankaku/zenkaku\tCancelAndIMEOff\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);
    config::ConfigHandler::SetConfig(config);
  }

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  {  // Cancel of Precomposition and deactivate IME
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Composition and deactivate IME
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    commands::Command command;
    SendKey("M", &session, &command);

    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Suggestion and deactivate IME
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    commands::Command command;
    SendKey("M", &session, &command);

    GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
    SendKey("O", &session, &command);
    ASSERT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Conversion and deactivate IME
    Session session(engine_.get());
    InitSessionToConversionWithAiueo(&session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Reverse conversion and deactivate IME
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);

    commands::Command command;

    // "[MO]" is a converted string like Kanji.
    // "MO" is an input string like Hiragana.
    SetupCommandForReverseConversion("[MO]", command.mutable_input());
    SetupMockForReverseConversion("[MO]", "MO");
    EXPECT_TRUE(session.SendCommand(&command));

    command.Clear();
    GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
    session.ConvertCancel(&command);
    ASSERT_TRUE(command.output().has_candidates());
    EXPECT_EQ(2, command.output().candidates().candidate_size());
    EXPECT_EQ("MOCHA", command.output().candidates().candidate(0).value());

    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_RESULT("[MO]", command);
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }
}

// TODO(matsuzakit): Update the expected result when b/5955618 is fixed.
TEST_F(SessionTest, CancelInPasswordMode_Issue5955618) {
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\tESC\tCancel\n"
        "Composition\tESC\tCancel\n"
        "Conversion\tESC\tCancel\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);
    config::ConfigHandler::SetConfig(config);
  }
  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  {  // Cancel of Precomposition in password field
     // Basically this is unusual because there is no character to be canceled
     // when Precomposition state.
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());  // should be consumed, anyway.

    EXPECT_TRUE(SendKey("ESC", &session, &command));
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
  }

  {  // Cancel of Composition in password field
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("ESC", &session, &command));
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
  }

  {  // Cancel of Conversion in password field
    Session session(engine_.get());
    InitSessionToConversionWithAiueo(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    // Actualy this works well because Cancel command in conversion mode
    // is mapped into ConvertCancel not EditCancel.
    commands::Command command;
    EXPECT_TRUE(TestSendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result());

    EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());
  }

  {  // Cancel of Reverse conversion in password field
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;

    // "[MO]" is a converted string like Kanji.
    // "MO" is an input string like Hiragana.
    SetupCommandForReverseConversion("[MO]", command.mutable_input());
    SetupMockForReverseConversion("[MO]", "MO");
    EXPECT_TRUE(session.SendCommand(&command));

    // Actualy this works well because Cancel command in conversion mode
    // is mapped into ConvertCancel not EditCancel.
    EXPECT_TRUE(TestSendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result());
    EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());

    // The second escape key will be mapped into EditCancel.
    EXPECT_TRUE(TestSendKey("ESC", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("ESC", &session, &command));
    // This behavior is the bug of b/5955618.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
    EXPECT_RESULT("[MO]", command);
  }
}

// TODO(matsuzakit): Update the expected result when b/5955618 is fixed.
TEST_F(SessionTest, CancelAndIMEOffInPasswordMode_Issue5955618) {
  {
    config::Config config;
    const string custom_keymap_table =
        "status\tkey\tcommand\n"
        "Precomposition\thankaku/zenkaku\tCancelAndIMEOff\n"
        "Composition\thankaku/zenkaku\tCancelAndIMEOff\n"
        "Conversion\thankaku/zenkaku\tCancelAndIMEOff\n";
    config.set_session_keymap(config::Config::CUSTOM);
    config.set_custom_keymap_table(custom_keymap_table);
    config::ConfigHandler::SetConfig(config);
  }
  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  {  // Cancel of Precomposition and deactivate IME in password field.
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    // Current behavior seems to be a bug.
    // This command should deactivate the IME.
    ASSERT_FALSE(command.output().has_status())
        << "Congrats! b/5955618 seems to be fixed.";
    // Ideally the following condition should be satisfied.
    // EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Composition and deactivate IME in password field
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());

    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    // Following behavior seems to be a bug.
    // This command should deactivate the IME.
    ASSERT_FALSE(command.output().has_status())
        << "Congrats! b/5955618 seems to be fixed.";
    // Ideally the following condition should be satisfied.
    // EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Conversion and deactivate IME in password field
    Session session(engine_.get());
    InitSessionToConversionWithAiueo(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;
    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    command.Clear();
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
    EXPECT_EQ("", GetComposition(command));
    EXPECT_EQ(0, command.output().candidates().candidate_size());
    EXPECT_FALSE(command.output().has_result());
    // Following behavior seems to be a bug.
    // This command should deactivate the IME.
    ASSERT_FALSE(command.output().has_status())
        << "Congrats! b/5955618 seems to be fixed.";
    // Ideally the following condition should be satisfied.
    // EXPECT_FALSE(command.output().status().activated());
  }

  {  // Cancel of Reverse conversion and deactivate IME in password field
    Session session(engine_.get());
    InitSessionToPrecomposition(&session);
    SwitchInputFieldType(commands::Context::PASSWORD, &session);

    commands::Command command;

    // "[MO]" is a converted string like Kanji.
    // "MO" is an input string like Hiragana.
    SetupCommandForReverseConversion("[MO]", command.mutable_input());
    SetupMockForReverseConversion("[MO]", "MO");
    EXPECT_TRUE(session.SendCommand(&command));

    EXPECT_TRUE(TestSendKey("hankaku/zenkaku", &session, &command));
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(SendKey("hankaku/zenkaku", &session, &command));
    // This behavior is the bug of b/5955618.
    // The result of TestSendKey and SendKey should be the same in terms of
    // |consumed()|.
    EXPECT_FALSE(command.output().consumed())
        << "Congrats! b/5955618 seems to be fixed";
    EXPECT_RESULT("[MO]", command);
    ASSERT_TRUE(command.output().has_status());
    // This behavior is the bug of b/5955618. IME should be deactivated.
    EXPECT_TRUE(command.output().status().activated())
        << "Congrats! b/5955618 seems to be fixed";
  }
}

// We use following represenetaion for indicating all state-change pass.
// State:
//   [PRECOMP] : Precomposition state
//   [COMP-L]  : Composition state with cursor at left most.
//   [COMP-M]  : Composition state with cursor at middle of composition.
//   [COMP-R]  : Composition state with cursor at right most.
//   [CONV-L]  : Conversion state with cursor at left most.
//   [CONV-M]  : Conversion state with cursor at middle of composition.
// State Change:
//  "abcdef" means composition characters.
//  "^" means suggestion/conversion window left-top position
//  "|" means caret position.
// NOTE:
//  It is not necessary to test in case as follows because they never occur.
//   - [PRECOMP] -> [PRECOMP]
//   - [PRECOMP] -> [COMP-M] or [COMP-L]
//   - [PRECOMP] -> [CONV-L] or [CONV-R]
//  Also it is not necessary to test in case of changing to CONVERSION state,
//  because conversion window is always shown under current cursor.
TEST_F(SessionTest, CaretManagePrecompositionToCompositionTest) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  Segments segments;
  const int kCaretInitialXpos = 10;
  commands::Rectangle rectangle;
  rectangle.set_x(kCaretInitialXpos);
  rectangle.set_y(0);
  rectangle.set_width(0);
  rectangle.set_height(0);

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  // [PRECOMP] -> [COMP-R]:
  //  Expectation: -> ^a|
  SetCaretLocation(rectangle, session.get());

  SendKey("M", session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());
}

TEST_F(SessionTest, CaretManageCompositionToCompositionTest) {
  Segments segments_m;
  {
    segments_m.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_m.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_moz;
  {
    segments_moz.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_moz.add_segment();
    segment->set_key("MOZ");
    segment->add_candidate()->value = "MOZUKU";
  }

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  commands::Command command;
  const int kCaretInitialXpos = 10;
  commands::Rectangle rectangle;
  rectangle.set_x(kCaretInitialXpos);
  rectangle.set_y(0);
  rectangle.set_width(0);
  rectangle.set_height(0);

  SetCaretLocation(rectangle, session.get());

  SendKey("M", session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-R] -> [COMP-R]:
  //  Expectation: ^mo| -> ^moz|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_moz, true);
  SendKey("Z", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-R] -> [COMP-R]:
  //  Expectation: ^moz| -> ^mo|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("Backspace", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-R] -> [COMP-M]:
  //  Expectation: ^mo| -> ^m|o
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorLeft(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-M] -> [COMP-R]:
  //  Expectation: ^m|o -> ^mo|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorToEnd(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-R] -> [COMP-L]:
  //  Expectation: ^mo| -> ^|mo
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorToBeginning(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-L] -> [COMP-M]:
  //  Expectation: ^|mo -> ^m|o
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  command.Clear();
  EXPECT_TRUE(session->MoveCursorRight(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  // [COMP-M] -> [COMP-L]:
  //  Expectation: ^m|o -> ^m|
  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);
  command.Clear();
  EXPECT_TRUE(session->Delete(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());
}

TEST_F(SessionTest, CaretManageConversionToCompositionTest) {
  // There are two ways to change state from CONVERSION to COMPOSITION,
  // One is canceling conversion with BS key. In this case cursor location
  // becomes right most and suggest position is left most.
  // The second is continuing typing under conversion. If user types key under
  // conversion, the IME commits selected candidate and creates new composition
  // at once.
  // For example:
  //    KeySequence: 'a' -> SP -> SP -> 'i'
  //    Expectation: a^|i (a and i are corresponding japanese characters)
  //    Actual: ^a|i
  // In the session side, we can only support the former case.

  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  Segments segments;
  const int kCaretInitialXpos = 10;
  commands::Rectangle rectangle;
  rectangle.set_x(kCaretInitialXpos);
  rectangle.set_y(0);
  rectangle.set_width(0);
  rectangle.set_height(0);

  Segments segments_m;
  {
    segments_m.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_m.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_moz;
  {
    segments_moz.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_moz.add_segment();
    segment->set_key("MOZ");
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_m_conv;
  {
    segments_m_conv.set_request_type(Segments::CONVERSION);
    Segment *segment;
    segment = segments_m_conv.add_segment();
    segment->set_key("M");
    segment->add_candidate()->value = "M";
    segment->add_candidate()->value = "m";
  }

  scoped_ptr<ConversionRequest> request_m_conv;

  // [CONV-L] -> [COMP-R]
  //  Expectation: ^|a -> ^a|
  SetCaretLocation(rectangle, session.get());

  SendKey("M", session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  command.Clear();
  request_m_conv.reset(new ConversionRequest);
  SetComposer(session.get(), request_m_conv.get());
  FillT13Ns(*request_m_conv, &segments_m_conv);
  GetConverterMock()->SetStartConversionForRequest(&segments_m_conv, true);
  EXPECT_TRUE(session->Convert(&command));

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  command.Clear();
  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);
  EXPECT_TRUE(session->ConvertCancel(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());

  // [CONV-M] -> [COMP-R]
  //  Expectation: ^a|b -> ^ab|
  session.reset(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());
  rectangle.set_x(kCaretInitialXpos);

  SetCaretLocation(rectangle, session.get());

  SendKey("M", session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  command.Clear();
  request_m_conv.reset(new ConversionRequest);
  SetComposer(session.get(), request_m_conv.get());
  FillT13Ns(*request_m_conv, &segments_m_conv);
  GetConverterMock()->SetStartConversionForRequest(&segments_m_conv, true);
  EXPECT_TRUE(session->Convert(&command));

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  SendSpecialKey(commands::KeyEvent::LEFT, session.get(), &command);

  rectangle.set_x(rectangle.x() + 5);
  SetCaretLocation(rectangle, session.get());

  command.Clear();
  GetConverterMock()->SetStartSuggestionForRequest(&segments_m, true);
  EXPECT_TRUE(session->ConvertCancel(&command));
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());
}

TEST_F(SessionTest, CaretJumpCaseTest) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  commands::Command command;
  Segments segments;
  const int kCaretInitialXpos = 10;
  const int kCaretInitialYpos = 12;
  commands::Rectangle rectangle;
  rectangle.set_x(kCaretInitialXpos);
  rectangle.set_y(kCaretInitialYpos);
  rectangle.set_width(0);
  rectangle.set_height(0);

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }

  Segments segments_moz;
  {
    segments_moz.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_moz.add_segment();
    segment->set_key("MOZ");
    segment->add_candidate()->value = "MOZUKU";
  }

  SetCaretLocation(rectangle, session.get());
  SendKey("M", session.get(), &command);

  // If Y-position of caret is jumped, composition text area is reset.
  rectangle.set_y(rectangle.y() + 200);
  SetCaretLocation(rectangle, session.get());
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);
  SendKey("O", session.get(), &command);
  EXPECT_EQ(rectangle.y(),
            command.output().candidates().composition_rectangle().y());

  // Even if X-position of caret is jumped, composition text area is not reset.
  rectangle.set_x(rectangle.x() + 200);
  SetCaretLocation(rectangle, session.get());
  GetConverterMock()->SetStartSuggestionForRequest(&segments_moz, true);
  SendKey("Z", session.get(), &command);
  EXPECT_EQ(kCaretInitialXpos,
            command.output().candidates().composition_rectangle().x());
}

TEST_F(SessionTest, DoNothingOnCompositionKeepingSuggestWindow) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  Segments segments_mo;
  {
    segments_mo.set_request_type(Segments::SUGGESTION);
    Segment *segment;
    segment = segments_mo.add_segment();
    segment->set_key("MO");
    segment->add_candidate()->value = "MOCHA";
    segment->add_candidate()->value = "MOZUKU";
  }
  GetConverterMock()->SetStartSuggestionForRequest(&segments_mo, true);

  commands::Command command;
  SendKey("M", &session, &command);
  EXPECT_TRUE(command.output().has_candidates());

  SendKey("Ctrl", &session, &command);
  EXPECT_TRUE(command.output().has_candidates());
}

TEST_F(SessionTest, ModeChangeOfConvertAtPunctuations) {
  config::Config config;
  config.set_use_auto_conversion(true);
  config::ConfigHandler::SetConfig(config);

  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  Segments segments_a_conv;
  {
    segments_a_conv.set_request_type(Segments::CONVERSION);
    Segment *segment;
    segment = segments_a_conv.add_segment();
    segment->set_key(kHiraganaA);
    segment->add_candidate()->value = kHiraganaA;
  }
  GetConverterMock()->SetStartConversionForRequest(&segments_a_conv, true);

  commands::Command command;
  SendKey("a", &session, &command);     // "あ|" (composition)
  EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());

  SendKey(".", &session, &command);     // "あ。|" (conversion)
  EXPECT_EQ(ImeContext::CONVERSION, session.context().state());

  SendKey("ESC", &session, &command);   // "あ。|" (composition)
  EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());

  SendKey("Left", &session, &command);  // "あ|。" (composition)
  EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());

  SendKey("i", &session, &command);     // "あい|。" (should be composition)
  EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());
}

TEST_F(SessionTest, SuppressSuggestion) {
  Session session(mock_data_engine_.get());
  InitSessionToPrecomposition(&session);

  commands::Command command;
  SendKey("a", &session, &command);
  EXPECT_TRUE(command.output().has_candidates());

  command.Clear();
  session.EditCancel(&command);
  EXPECT_FALSE(command.output().has_candidates());

  // Default behavior.
  SendKey("d", &session, &command);
  EXPECT_TRUE(command.output().has_candidates());

  // With an invalid identifer.  It should be the same with the
  // default behavior.
  SetSendKeyCommand("i", &command);
  command.mutable_input()->mutable_context()->add_experimental_features(
      "invalid_identifier");
  session.SendKey(&command);
  EXPECT_TRUE(command.output().has_candidates());

}

TEST_F(SessionTest, DeleteHistory) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  Segments segments;
  Segment *segment = segments.add_segment();
  segment->set_key("delete");
  segment->add_candidate()->value = "DeleteHistory";
  ConversionRequest request;
  SetComposer(session.get(), &request);
  GetConverterMock()->SetStartPredictionForRequest(&segments, true);

  // Type "del". Preedit = "でｌ".
  commands::Command command;
  EXPECT_TRUE(SendKey("d", session.get(), &command));
  EXPECT_TRUE(SendKey("e", session.get(), &command));
  EXPECT_TRUE(SendKey("l", session.get(), &command));
  EXPECT_PREEDIT("\xE3\x81\xA7\xEF\xBD\x8C", command);  //  "でｌ"

  // Start prediction. Preedit = "DeleteHistory".
  command.Clear();
  EXPECT_TRUE(session->PredictAndConvert(&command));
  EXPECT_TRUE(command.output().has_candidates());
  EXPECT_EQ(ImeContext::CONVERSION, session->context().state());
  EXPECT_PREEDIT("DeleteHistory", command);

  // Do DeleteHistory command. After that, the session should be back in
  // composition state and preedit gets back to "でｌ" again.
  EXPECT_TRUE(SendKey("Ctrl Delete", session.get(), &command));
  EXPECT_EQ(ImeContext::COMPOSITION, session->context().state());
  EXPECT_PREEDIT("\xE3\x81\xA7\xEF\xBD\x8C", command);  //  "でｌ"
}

TEST_F(SessionTest, SendKeyWithKeyString_Direct) {
  Session session(engine_.get());
  InitSessionToDirect(&session);

  commands::Command command;
  const char kZa[] = "\xE3\x81\x96";  // "ざ"
  SetSendKeyCommandWithKeyString(kZa, &command);
  EXPECT_TRUE(session.TestSendKey(&command));
  EXPECT_FALSE(command.output().consumed());
  command.mutable_output()->Clear();
  EXPECT_TRUE(session.SendKey(&command));
  EXPECT_FALSE(command.output().consumed());
}

TEST_F(SessionTest, SendKeyWithKeyString) {
  Session session(engine_.get());
  InitSessionToPrecomposition(&session);

  commands::Command command;

  // Test for precomposition state.
  EXPECT_EQ(ImeContext::PRECOMPOSITION, session.context().state());
  const char kZa[] = "\xE3\x81\x96";  // "ざ"
  SetSendKeyCommandWithKeyString(kZa, &command);
  EXPECT_TRUE(session.TestSendKey(&command));
  EXPECT_TRUE(command.output().consumed());
  command.mutable_output()->Clear();
  EXPECT_TRUE(session.SendKey(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_PREEDIT(kZa, command);

  command.Clear();

  // Test for composition state.
  EXPECT_EQ(ImeContext::COMPOSITION, session.context().state());
  const char kOnsenManju[] = "\xE2\x99\xA8\xE9\xA5\x85\xE9\xA0\xAD";  // "♨饅頭"
  SetSendKeyCommandWithKeyString(kOnsenManju, &command);
  EXPECT_TRUE(session.TestSendKey(&command));
  EXPECT_TRUE(command.output().consumed());
  command.mutable_output()->Clear();
  EXPECT_TRUE(session.SendKey(&command));
  EXPECT_TRUE(command.output().consumed());
  EXPECT_PREEDIT(string(kZa) + kOnsenManju, command);
}

TEST_F(SessionTest, IndirectImeOnOff) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  {
    commands::Command command;
    // IMEOff
    SendSpecialKey(commands::KeyEvent::OFF, session.get(), &command);
  }
  {
    commands::Command command;
    // 'a'
    TestSendKeyWithModeAndActivated(
        "a", true, commands::HIRAGANA, session.get(), &command);
    EXPECT_TRUE(command.output().consumed());
  }
  {
    commands::Command command;
    // 'a'
    SendKeyWithModeAndActivated(
        "a", true, commands::HIRAGANA, session.get(), &command);
    EXPECT_TRUE(command.output().consumed());
    EXPECT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated())
        << "Should be activated.";
  }
  {
    commands::Command command;
    // 'a'
    TestSendKeyWithModeAndActivated(
        "a", false, commands::HIRAGANA, session.get(), &command);
    EXPECT_FALSE(command.output().consumed());
  }
  {
    commands::Command command;
    // 'a'
    SendKeyWithModeAndActivated(
        "a", false, commands::HIRAGANA, session.get(), &command);
    EXPECT_FALSE(command.output().consumed());
    EXPECT_FALSE(command.output().has_result())
        << "Indirect IME off flushes ongoing composition";
    EXPECT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated())
        << "Should be inactivated.";
  }
}

TEST_F(SessionTest, MakeSureIMEOn) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToDirect(session.get());

  {
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_ON_IME, &command);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
  }

  {
    // Make sure we can change the input mode.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_ON_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::FULL_KATAKANA);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
  }

  {
    // Make sure we can change the input mode again.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_ON_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::HIRAGANA);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_TRUE(command.output().status().activated());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
  }

  {
    // commands::DIRECT is not supported for the composition_mode.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_ON_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::DIRECT);
    EXPECT_FALSE(session->SendCommand(&command));
  }
}

TEST_F(SessionTest, MakeSureIMEOff) {
  scoped_ptr<Session> session(new Session(engine_.get()));
  InitSessionToPrecomposition(session.get());

  {
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_OFF_IME, &command);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
  }

  {
    // Make sure we can change the input mode.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_OFF_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::FULL_KATAKANA);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
    EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
  }

  {
    // Make sure we can change the input mode again.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_OFF_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::HIRAGANA);

    ASSERT_TRUE(session->SendCommand(&command));
    EXPECT_TRUE(command.output().consumed());
    ASSERT_TRUE(command.output().has_status());
    EXPECT_FALSE(command.output().status().activated());
    EXPECT_EQ(commands::HIRAGANA, command.output().status().mode());
  }

  {
    // commands::DIRECT is not supported for the composition_mode.
    commands::Command command;
    SetSendCommandCommand(commands::SessionCommand::TURN_OFF_IME, &command);
    command.mutable_input()->mutable_command()->set_composition_mode(
        commands::DIRECT);
    EXPECT_FALSE(session->SendCommand(&command));
  }

  {
    // Make sure SessionCommand::TURN_OFF_IME terminates the existing
    // composition.

    InitSessionToPrecomposition(session.get());

    // Set up converter.
    {
      commands::Command command;

      Segments segments;
      InsertCharacterChars("aiueo", session.get(), &command);
      ConversionRequest request;
      SetComposer(session.get(), &request);
      SetAiueo(&segments);
      FillT13Ns(request, &segments);
      GetConverterMock()->SetCommitSegmentValue(&segments, true);
    }

    // Send SessionCommand::TURN_OFF_IME to commit composition.
    {
      commands::Command command;
      SetSendCommandCommand(commands::SessionCommand::TURN_OFF_IME, &command);
      command.mutable_input()->mutable_command()->set_composition_mode(
          commands::FULL_KATAKANA);
      ASSERT_TRUE(session->SendCommand(&command));
      EXPECT_RESULT(kAiueo, command);
      EXPECT_TRUE(command.output().consumed());
      ASSERT_TRUE(command.output().has_status());
      EXPECT_FALSE(command.output().status().activated());
      EXPECT_EQ(commands::FULL_KATAKANA, command.output().status().mode());
    }
  }
}

}  // namespace session
}  // namespace mozc
