1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96

ash / public / cpp / accelerator_keycode_lookup_cache_unittest.cc [blame]

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

#include "ash/public/cpp/accelerator_keycode_lookup_cache.h"

#include <memory>
#include <string>

#include "ui/base/ime/ash/input_method_manager.h"
#include "ui/base/ime/ash/mock_input_method_manager.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace ash {

using KeyCodeLookupEntry = AcceleratorKeycodeLookupCache::KeyCodeLookupEntry;

class AcceleratorKeycodeLookupCacheTest : public testing::Test {
 public:
  class TestInputMethodManager : public input_method::MockInputMethodManager {
   public:
    void AddObserver(
        input_method::InputMethodManager::Observer* observer) override {
      observers_.AddObserver(observer);
    }

    void RemoveObserver(
        input_method::InputMethodManager::Observer* observer) override {
      observers_.RemoveObserver(observer);
    }

    // Calls all observers with Observer::InputMethodChanged
    void NotifyInputMethodChanged() {
      for (auto& observer : observers_) {
        observer.InputMethodChanged(
            /*manager=*/this, /*profile=*/nullptr, /*show_message=*/false);
      }
    }

    base::ObserverList<InputMethodManager::Observer>::Unchecked observers_;
  };

  AcceleratorKeycodeLookupCacheTest() {
    input_method_manager_ = new TestInputMethodManager();
    input_method::InputMethodManager::Initialize(input_method_manager_);

    layout_engine_ = std::make_unique<ui::StubKeyboardLayoutEngine>();
    ui::KeyboardLayoutEngineManager::ResetKeyboardLayoutEngine();
    ui::KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
        layout_engine_.get());

    lookup_cache_ = std::make_unique<AcceleratorKeycodeLookupCache>();
  }

  ~AcceleratorKeycodeLookupCacheTest() override = default;

 protected:
  std::map<std::pair<ui::KeyboardCode, bool>, KeyCodeLookupEntry> cache() {
    return lookup_cache_->key_code_to_cache_entry_;
  }

  std::unique_ptr<AcceleratorKeycodeLookupCache> lookup_cache_;
  std::unique_ptr<ui::StubKeyboardLayoutEngine> layout_engine_;
  // Test global singleton. Delete is handled by InputMethodManager::Shutdown().
  raw_ptr<TestInputMethodManager> input_method_manager_;
};

TEST_F(AcceleratorKeycodeLookupCacheTest, ImeChanged) {
  const std::u16string expected = u"a";

  EXPECT_TRUE(cache().empty());
  lookup_cache_->InsertOrAssign(ui::KeyboardCode::VKEY_A,
                                /*remap_positional_key=*/false,
                                ui::DomCode::NONE, ui::DomKey::NONE,
                                ui::KeyboardCode::VKEY_A, expected);
  // Expect the cache to be populated.
  std::optional<KeyCodeLookupEntry> found_entry = lookup_cache_->Find(
      ui::KeyboardCode::VKEY_A, /*remap_positional_key=*/false);
  EXPECT_TRUE(found_entry.has_value());
  EXPECT_EQ(expected, found_entry->key_display);

  // Trigger IME change event, expect the cache to be cleared.
  input_method_manager_->NotifyInputMethodChanged();
  EXPECT_TRUE(cache().empty());
  found_entry = lookup_cache_->Find(ui::KeyboardCode::VKEY_A,
                                    /*remap_positional_key=*/false);
  EXPECT_FALSE(found_entry.has_value());
}

}  // namespace ash