chromium/chrome/browser/ash/input_method/grammar_manager_unittest.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/input_method/grammar_manager.h"

#include "base/test/metrics/histogram_tester.h"
#include "chrome/browser/ash/input_method/assistive_window_properties.h"
#include "chrome/browser/ash/input_method/grammar_service_client.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/services/machine_learning/public/cpp/fake_service_connection.h"
#include "components/spellcheck/common/spellcheck_result.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/ash/ime_bridge.h"
#include "ui/base/ime/ash/mock_ime_input_context_handler.h"
#include "ui/base/ime/text_input_flags.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/keycodes/dom/dom_code.h"

namespace ash {
namespace input_method {
namespace {

using ::testing::_;

const char16_t kShowGrammarSuggestionMessage[] =
    u"Grammar correction suggested. Press tab to access; escape to dismiss.";
const char16_t kDismissGrammarSuggestionMessage[] = u"Suggestion dismissed.";
const char16_t kAcceptGrammarSuggestionMessage[] = u"Suggestion accepted.";
const char16_t kIgnoreGrammarSuggestionMessage[] = u"Suggestion ignored.";
const char16_t kSuggestionButtonMessage[] =
    u"Suggestion correct. Button. Press enter to accept; escape to dismiss.";
const char16_t kIgnoreButtonMessage[] =
    u"Ignore suggestion. Button. Press enter to ignore the suggestion; escape "
    u"to dismiss.";

class TestGrammarServiceClient : public GrammarServiceClient {
 public:
  TestGrammarServiceClient() {}
  ~TestGrammarServiceClient() override = default;

  bool RequestTextCheck(Profile* profile,
                        const std::u16string& text,
                        TextCheckCompleteCallback callback) override {
    std::vector<ui::GrammarFragment> grammar_results;
    for (size_t i = 0; i < text.size(); i++) {
      if (text.substr(i, 5) == u"error") {
        grammar_results.emplace_back(gfx::Range(i, i + 5), "correct");
      }
    }
    std::move(callback).Run(true, grammar_results);
    return true;
  }
};

ui::KeyEvent CreateKeyEvent(const ui::DomCode& code) {
  return ui::KeyEvent(ui::EventType::kKeyPressed, ui::VKEY_UNKNOWN, code,
                      ui::EF_NONE, ui::DomKey::NONE, ui::EventTimeForNow());
}

class MockSuggestionHandler : public SuggestionHandlerInterface {
 public:
  MOCK_METHOD(bool,
              DismissSuggestion,
              (int context_id, std::string* error),
              (override));
  MOCK_METHOD(bool,
              SetSuggestion,
              (int context_id,
               const ui::ime::SuggestionDetails& details,
               std::string* error),
              (override));
  MOCK_METHOD(bool,
              AcceptSuggestion,
              (int context_id, std::string* error),
              (override));
  MOCK_METHOD(void,
              OnSuggestionsChanged,
              (const std::vector<std::string>& suggestions),
              (override));
  MOCK_METHOD(bool,
              SetButtonHighlighted,
              (int context_id,
               const ui::ime::AssistiveWindowButton& button,
               bool highlighted,
               std::string* error),
              (override));
  MOCK_METHOD(void,
              ClickButton,
              (const ui::ime::AssistiveWindowButton& button),
              (override));
  MOCK_METHOD(bool,
              AcceptSuggestionCandidate,
              (int context_id,
               const std::u16string& candidate,
               size_t delete_previous_utf16_len,
               bool use_replace_surrounding_text,
               std::string* error),
              (override));
  MOCK_METHOD(bool,
              SetAssistiveWindowProperties,
              (int context_id,
               const AssistiveWindowProperties& assistive_window,
               std::string* error),
              (override));
  MOCK_METHOD(void, Announce, (const std::u16string& message), (override));
};

class GrammarManagerTest : public testing::Test {
 protected:
  void SetUp() override {
    profile_ = std::make_unique<TestingProfile>();
    IMEBridge::Get()->SetInputContextHandler(&mock_ime_input_context_handler_);
    chromeos::machine_learning::ServiceConnection::
        UseFakeServiceConnectionForTesting(&fake_service_connection_);
    chromeos::machine_learning::ServiceConnection::GetInstance()->Initialize();
  }

  content::BrowserTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};

  std::unique_ptr<TestingProfile> profile_;
  chromeos::machine_learning::FakeServiceConnectionImpl
      fake_service_connection_;
  MockIMEInputContextHandler mock_ime_input_context_handler_;
};

TEST_F(GrammarManagerTest, HandlesSingleGrammarCheckResult) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  manager.OnFocus(1, SpellcheckMode::kUnspecified);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 1u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
  histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Grammar.Actions",
                                      0 /*GrammarAction::kUnderlined*/, 1);
}

TEST_F(GrammarManagerTest, RecordsUnderlinesMetricsWithoutDups) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  manager.OnFocus(1, SpellcheckMode::kUnspecified);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error error", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));
  histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Grammar.Actions",
                                      0 /*GrammarAction::kUnderlined*/, 2);

  manager.OnSurroundingTextChanged(u"There is error error error",
                                   gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));
  histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Grammar.Actions",
                                      0 /*GrammarAction::kUnderlined*/, 3);
}

TEST_F(GrammarManagerTest, DoesNotRunGrammarCheckOnTextFieldWithSpellcheckOff) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  manager.OnFocus(1, SpellcheckMode::kDisabled);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 0u);
  histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Grammar.Actions",
                                      0 /*GrammarAction::kUnderlined*/, 0);
}

TEST_F(GrammarManagerTest, ChecksLastSentenceImmediately) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error. And another error.",
                                   gfx::Range(20));
  task_environment_.FastForwardBy(base::Milliseconds(250));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 1u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
}

TEST_F(GrammarManagerTest, ChecksBothLastAndCurrentSentence) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error. And another error.",
                                   gfx::Range(20));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 2u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
  EXPECT_EQ(grammar_fragments[1].range, gfx::Range(28, 33));
  EXPECT_EQ(grammar_fragments[1].suggestion, "correct");
}

TEST_F(GrammarManagerTest, HandlesMultipleGrammarCheckResults) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 2u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
  EXPECT_EQ(grammar_fragments[1].range, gfx::Range(15, 20));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");
}

TEST_F(GrammarManagerTest, ClearsPreviousMarkersUponGettingNewResults) {
  MockSuggestionHandler mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 1u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");

  manager.OnSurroundingTextChanged(u"There is a new error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto updated_grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(updated_grammar_fragments.size(), 1u);
  EXPECT_EQ(updated_grammar_fragments[0].range, gfx::Range(15, 20));
  EXPECT_EQ(updated_grammar_fragments[0].suggestion, "correct");
}

TEST_F(GrammarManagerTest, ShowsAndDismissesGrammarSuggestion) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  AssistiveWindowProperties expected_properties;
  expected_properties.type = ash::ime::AssistiveWindowType::kGrammarSuggestion;
  expected_properties.candidates = {u"correct"};
  expected_properties.visible = true;
  expected_properties.announce_string = kShowGrammarSuggestionMessage;

  EXPECT_CALL(mock_suggestion_handler,
              SetAssistiveWindowProperties(1, expected_properties, _));

  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(10, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));
  histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions",
                                     1 /*GrammarAction::kWindowShown*/, 1);

  EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _));
  EXPECT_CALL(mock_suggestion_handler,
              Announce(std::u16string(kDismissGrammarSuggestionMessage)));

  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ESCAPE));
}

TEST_F(GrammarManagerTest, DoesntShowGrammarSuggestionWhenUndoWindowIsShown) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  mock_ime_input_context_handler_.SetAutocorrectRange(gfx::Range(9, 14),
                                                      base::DoNothing());
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  auto grammar_fragments =
      mock_ime_input_context_handler_.get_grammar_fragments();
  EXPECT_EQ(grammar_fragments.size(), 1u);
  EXPECT_EQ(grammar_fragments[0].range, gfx::Range(9, 14));
  EXPECT_EQ(grammar_fragments[0].suggestion, "correct");

  // No EXPECT_CALL comparing with the last test case because suggestion window
  // should not show.

  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));
  histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions",
                                     1 /*GrammarAction::kWindowShown*/, 0);
}

TEST_F(GrammarManagerTest, DismissesSuggestionWhenSelectingARange) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  AssistiveWindowProperties expected_properties;
  expected_properties.type = ash::ime::AssistiveWindowType::kGrammarSuggestion;
  expected_properties.candidates = {u"correct"};
  expected_properties.visible = true;
  expected_properties.announce_string = kShowGrammarSuggestionMessage;

  EXPECT_CALL(mock_suggestion_handler,
              SetAssistiveWindowProperties(1, expected_properties, _));

  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(10, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));

  EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _));

  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(9, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(9, 10));
}

TEST_F(GrammarManagerTest, HighlightsAndCommitsGrammarSuggestionWithTab) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  mock_ime_input_context_handler_.Reset();

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(10, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));

  ui::ime::AssistiveWindowButton suggestion_button{
      .id = ui::ime::ButtonId::kSuggestion,
      .window_type = ash::ime::AssistiveWindowType::kGrammarSuggestion,
      .announce_string = kSuggestionButtonMessage,
  };
  EXPECT_CALL(mock_suggestion_handler,
              SetButtonHighlighted(1, suggestion_button, true, _));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::TAB));
  EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _));
  EXPECT_CALL(mock_suggestion_handler,
              Announce(std::u16string(kAcceptGrammarSuggestionMessage)));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ENTER));
  task_environment_.FastForwardBy(base::Milliseconds(200));

  EXPECT_EQ(
      mock_ime_input_context_handler_.delete_surrounding_text_call_count(), 1);
  auto deleteSurroundingTextArg =
      mock_ime_input_context_handler_.last_delete_surrounding_text_arg();
  EXPECT_EQ(deleteSurroundingTextArg.num_char16s_before_cursor, 1u);
  EXPECT_EQ(deleteSurroundingTextArg.num_char16s_after_cursor, 4u);

  EXPECT_EQ(mock_ime_input_context_handler_.commit_text_call_count(), 1);
  EXPECT_EQ(mock_ime_input_context_handler_.last_commit_text(), u"correct");
  histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions",
                                     2 /*GrammarAction::kAccepted*/, 1);
}

TEST_F(GrammarManagerTest, HighlightsAndCommitsGrammarSuggestionWithUpArrow) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  mock_ime_input_context_handler_.Reset();

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(10, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));

  ui::ime::AssistiveWindowButton suggestion_button{
      .id = ui::ime::ButtonId::kSuggestion,
      .window_type = ash::ime::AssistiveWindowType::kGrammarSuggestion,
      .announce_string = kSuggestionButtonMessage,
  };
  EXPECT_CALL(mock_suggestion_handler,
              SetButtonHighlighted(1, suggestion_button, true, _));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ARROW_UP));
  EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _));
  EXPECT_CALL(mock_suggestion_handler,
              Announce(std::u16string(kAcceptGrammarSuggestionMessage)));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ENTER));
  task_environment_.FastForwardBy(base::Milliseconds(200));

  EXPECT_EQ(
      mock_ime_input_context_handler_.delete_surrounding_text_call_count(), 1);
  auto deleteSurroundingTextArg =
      mock_ime_input_context_handler_.last_delete_surrounding_text_arg();
  EXPECT_EQ(deleteSurroundingTextArg.num_char16s_before_cursor, 1u);
  EXPECT_EQ(deleteSurroundingTextArg.num_char16s_after_cursor, 4u);

  EXPECT_EQ(mock_ime_input_context_handler_.commit_text_call_count(), 1);
  EXPECT_EQ(mock_ime_input_context_handler_.last_commit_text(), u"correct");
  histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions",
                                     2 /*GrammarAction::kAccepted*/, 1);
}

TEST_F(GrammarManagerTest, IgnoresGrammarSuggestion) {
  ::testing::StrictMock<MockSuggestionHandler> mock_suggestion_handler;
  GrammarManager manager(profile_.get(),
                         std::make_unique<TestGrammarServiceClient>(),
                         &mock_suggestion_handler);
  base::HistogramTester histogram_tester;

  mock_ime_input_context_handler_.Reset();

  manager.OnFocus(1);
  manager.OnSurroundingTextChanged(u"", gfx::Range(0));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(0));
  task_environment_.FastForwardBy(base::Milliseconds(2500));

  EXPECT_EQ(mock_ime_input_context_handler_.get_grammar_fragments().size(), 1u);
  EXPECT_CALL(mock_suggestion_handler, SetAssistiveWindowProperties(1, _, _));
  mock_ime_input_context_handler_.set_cursor_range(gfx::Range(10, 10));
  manager.OnSurroundingTextChanged(u"There is error.", gfx::Range(10));

  ui::ime::AssistiveWindowButton suggestion_button{
      .id = ui::ime::ButtonId::kSuggestion,
      .window_type = ash::ime::AssistiveWindowType::kGrammarSuggestion,
      .announce_string = kSuggestionButtonMessage,
  };
  ui::ime::AssistiveWindowButton ignore_button{
      .id = ui::ime::ButtonId::kIgnoreSuggestion,
      .window_type = ash::ime::AssistiveWindowType::kGrammarSuggestion,
      .announce_string = kIgnoreButtonMessage,
  };

  EXPECT_CALL(mock_suggestion_handler,
              SetButtonHighlighted(1, suggestion_button, true, _));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::TAB));
  EXPECT_CALL(mock_suggestion_handler,
              SetButtonHighlighted(1, ignore_button, true, _));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::TAB));
  EXPECT_CALL(mock_suggestion_handler, DismissSuggestion(1, _));
  EXPECT_CALL(mock_suggestion_handler,
              Announce(std::u16string(kIgnoreGrammarSuggestionMessage)));
  manager.OnKeyEvent(CreateKeyEvent(ui::DomCode::ENTER));

  EXPECT_EQ(mock_ime_input_context_handler_.get_grammar_fragments().size(), 0u);
  EXPECT_EQ(
      mock_ime_input_context_handler_.delete_surrounding_text_call_count(), 0);
  EXPECT_EQ(mock_ime_input_context_handler_.commit_text_call_count(), 0);
  histogram_tester.ExpectBucketCount("InputMethod.Assistive.Grammar.Actions",
                                     3 /*GrammarAction::kIgnored*/, 1);

  manager.OnSurroundingTextChanged(u"There is error. There is error.",
                                   gfx::Range(20));
  task_environment_.FastForwardBy(base::Milliseconds(2500));
  EXPECT_EQ(mock_ime_input_context_handler_.get_grammar_fragments().size(), 0u);
}

}  // namespace
}  // namespace input_method
}  // namespace ash