7 #include "flutter/shell/platform/windows/testing/mock_direct_manipulation.h"
8 #include "flutter/shell/platform/windows/testing/mock_text_input_manager.h"
9 #include "flutter/shell/platform/windows/testing/mock_window.h"
10 #include "flutter/shell/platform/windows/testing/mock_windows_proc_table.h"
11 #include "gmock/gmock.h"
12 #include "gtest/gtest.h"
16 using testing::InSequence;
17 using testing::Invoke;
18 using testing::Return;
23 TEST(MockWindow, CreateDestroy) {
28 TEST(MockWindow, GetDpiAfterCreate) {
30 ASSERT_TRUE(window.GetDpi() > 0);
33 TEST(MockWindow, VerticalScroll) {
35 const int scroll_amount = 10;
38 EXPECT_CALL(window, OnScroll(0, -scroll_amount / 120.0,
39 kFlutterPointerDeviceKindMouse, 0))
42 window.InjectWindowMessage(WM_MOUSEWHEEL, MAKEWPARAM(0, scroll_amount), 0);
45 TEST(MockWindow, OnImeCompositionCompose) {
46 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
47 auto* text_input_manager =
new MockTextInputManager();
48 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
49 MockWindow window(std::move(windows_proc_table),
50 std::move(text_input_manager_ptr));
51 EXPECT_CALL(*text_input_manager, GetComposingString())
53 Return(std::optional<std::u16string>(std::u16string(u
"nihao"))));
54 EXPECT_CALL(*text_input_manager, GetResultString())
56 Return(std::optional<std::u16string>(std::u16string(u
"`}"))));
57 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition()).Times(0);
59 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"nihao"), 5)).Times(1);
60 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"`}"), 0)).Times(0);
61 EXPECT_CALL(window, OnComposeCommit()).Times(0);
62 ON_CALL(window, OnImeComposition)
63 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
64 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
67 window.InjectWindowMessage(WM_IME_COMPOSITION, 0, GCS_COMPSTR);
71 TEST(MockWindow, OnImeCompositionDefaultsKoreanCursorToCompositionEnd) {
72 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
73 auto* text_input_manager =
new MockTextInputManager();
74 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
75 MockWindow window(std::move(windows_proc_table),
76 std::move(text_input_manager_ptr));
77 EXPECT_CALL(*text_input_manager, GetComposingString())
79 Return(std::optional<std::u16string>(std::u16string(u
"다"))));
80 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition()).Times(0);
82 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"다"), 1)).Times(1);
83 EXPECT_CALL(window, OnComposeCommit()).Times(0);
84 ON_CALL(window, OnImeComposition)
85 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
86 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
88 window.InjectWindowMessage(WM_IME_COMPOSITION, 0, GCS_COMPSTR);
91 TEST(MockWindow, OnImeCompositionResult) {
92 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
93 auto* text_input_manager =
new MockTextInputManager();
94 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
95 MockWindow window(std::move(windows_proc_table),
96 std::move(text_input_manager_ptr));
97 EXPECT_CALL(*text_input_manager, GetComposingString())
99 Return(std::optional<std::u16string>(std::u16string(u
"nihao"))));
100 EXPECT_CALL(*text_input_manager, GetResultString())
102 Return(std::optional<std::u16string>(std::u16string(u
"`}"))));
103 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition()).Times(0);
105 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"nihao"), 0)).Times(0);
106 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"`}"), 2)).Times(1);
107 EXPECT_CALL(window, OnComposeCommit()).Times(1);
108 ON_CALL(window, OnImeComposition)
109 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
110 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
113 window.InjectWindowMessage(WM_IME_COMPOSITION, 0, GCS_RESULTSTR);
116 TEST(MockWindow, OnImeCompositionResultAndCompose) {
117 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
118 auto* text_input_manager =
new MockTextInputManager();
119 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
120 MockWindow window(std::move(windows_proc_table),
121 std::move(text_input_manager_ptr));
127 EXPECT_CALL(*text_input_manager, GetResultString())
129 Return(std::optional<std::u16string>(std::u16string(u
"今日"))));
130 EXPECT_CALL(*text_input_manager, GetComposingString())
132 Return(std::optional<std::u16string>(std::u16string(u
"は"))));
136 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"今日"), 2)).Times(1);
137 EXPECT_CALL(window, OnComposeCommit()).Times(1);
138 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"は"), 1)).Times(1);
141 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition()).Times(0);
143 ON_CALL(window, OnImeComposition)
144 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
145 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
149 window.InjectWindowMessage(WM_IME_COMPOSITION, 0,
150 GCS_COMPSTR | GCS_RESULTSTR);
153 TEST(MockWindow, OnImeCompositionUsesCursorPositionWhenProvided) {
154 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
155 auto* text_input_manager =
new MockTextInputManager();
156 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
157 MockWindow window(std::move(windows_proc_table),
158 std::move(text_input_manager_ptr));
159 EXPECT_CALL(*text_input_manager, GetComposingString())
161 Return(std::optional<std::u16string>(std::u16string(u
"nihao"))));
162 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition())
163 .WillOnce(Return(2));
165 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"nihao"), 2)).Times(1);
166 EXPECT_CALL(window, OnComposeCommit()).Times(0);
167 ON_CALL(window, OnImeComposition)
168 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
169 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
171 window.InjectWindowMessage(WM_IME_COMPOSITION, 0,
172 GCS_COMPSTR | GCS_CURSORPOS);
175 TEST(MockWindow, OnImeCompositionFallsBackToTextEndForInvalidCursorPosition) {
176 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
177 auto* text_input_manager =
new MockTextInputManager();
178 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
179 MockWindow window(std::move(windows_proc_table),
180 std::move(text_input_manager_ptr));
181 EXPECT_CALL(*text_input_manager, GetComposingString())
183 Return(std::optional<std::u16string>(std::u16string(u
"nihao"))));
184 EXPECT_CALL(*text_input_manager, GetComposingCursorPosition())
185 .WillOnce(Return(-1));
187 EXPECT_CALL(window, OnComposeChange(std::u16string(u
"nihao"), 5)).Times(1);
188 EXPECT_CALL(window, OnComposeCommit()).Times(0);
189 ON_CALL(window, OnImeComposition)
190 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
191 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
193 window.InjectWindowMessage(WM_IME_COMPOSITION, 0,
194 GCS_COMPSTR | GCS_CURSORPOS);
197 TEST(MockWindow, OnImeCompositionClearChange) {
198 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
199 auto* text_input_manager =
new MockTextInputManager();
200 std::unique_ptr<TextInputManager> text_input_manager_ptr(text_input_manager);
201 MockWindow window(std::move(windows_proc_table),
202 std::move(text_input_manager_ptr));
203 EXPECT_CALL(window, OnComposeChange(std::u16string(u
""), 0)).Times(1);
204 EXPECT_CALL(window, OnComposeCommit()).Times(1);
205 ON_CALL(window, OnImeComposition)
206 .WillByDefault(Invoke(&window, &MockWindow::CallOnImeComposition));
207 EXPECT_CALL(window, OnImeComposition(_, _, _)).Times(1);
211 window.InjectWindowMessage(WM_IME_COMPOSITION, 0, 0);
214 TEST(MockWindow, HorizontalScroll) {
216 const int scroll_amount = 10;
218 EXPECT_CALL(window, OnScroll(scroll_amount / 120.0, 0,
219 kFlutterPointerDeviceKindMouse, 0))
222 window.InjectWindowMessage(WM_MOUSEHWHEEL, MAKEWPARAM(0, scroll_amount), 0);
227 const double mouse_x = 10.0;
228 const double mouse_y = 20.0;
231 OnPointerMove(mouse_x, mouse_y, kFlutterPointerDeviceKindMouse, 0,
234 EXPECT_CALL(window, OnPointerLeave(mouse_x, mouse_y,
235 kFlutterPointerDeviceKindMouse, 0))
238 window.InjectWindowMessage(WM_MOUSEMOVE, 0, MAKELPARAM(mouse_x, mouse_y));
239 window.InjectWindowMessage(WM_MOUSELEAVE, 0, 0);
244 EXPECT_CALL(window, OnKey(_, _, _, _, _, _, _)).Times(1);
245 LPARAM lparam = CreateKeyEventLparam(42,
false,
false);
247 window.InjectWindowMessage(WM_KEYDOWN, 16, lparam);
252 EXPECT_CALL(window, OnKey(_, _, _, _, _, _, _)).Times(1);
253 LPARAM lparam = CreateKeyEventLparam(42,
false,
true);
255 window.InjectWindowMessage(WM_KEYUP, 16, lparam);
260 EXPECT_CALL(window, OnKey(_, _, _, _, _, _, _)).Times(1);
261 LPARAM lparam = CreateKeyEventLparam(42,
false,
false);
263 window.InjectWindowMessage(WM_SYSKEYDOWN, 16, lparam);
268 EXPECT_CALL(window, OnKey(_, _, _, _, _, _, _)).Times(1);
271 EXPECT_CALL(window, Win32DefWindowProc(_, _, _, _)).Times(0);
272 LPARAM lparam = CreateKeyEventLparam(42,
false,
true);
274 window.InjectWindowMessage(WM_SYSKEYUP, 16, lparam);
277 TEST(MockWindow, KeyDownPrintable) {
279 LPARAM lparam = CreateKeyEventLparam(30,
false,
false);
283 std::function<void(
bool)>
callback) {
286 EXPECT_CALL(window, OnKey(65, 30, WM_KEYDOWN, 0,
false,
false, _))
288 .WillOnce(respond_false);
289 EXPECT_CALL(window, OnText(_)).Times(1);
290 std::array<Win32Message, 2> messages = {
291 Win32Message{WM_KEYDOWN, 65, lparam, kWmResultDontCheck},
292 Win32Message{WM_CHAR, 65, lparam, kWmResultDontCheck}};
293 window.InjectMessageList(2, messages.data());
296 TEST(MockWindow, KeyDownWithCtrl) {
300 std::array<BYTE, 256> keyboard_state;
301 keyboard_state[VK_CONTROL] = -1;
302 SetKeyboardState(keyboard_state.data());
304 LPARAM lparam = CreateKeyEventLparam(30,
false,
false);
308 EXPECT_CALL(window, OnKey(65, 30, WM_KEYDOWN, 0,
false,
false, _)).Times(1);
309 EXPECT_CALL(window, OnText(_)).Times(0);
311 window.InjectWindowMessage(WM_KEYDOWN, 65, lparam);
313 keyboard_state.fill(0);
314 SetKeyboardState(keyboard_state.data());
317 TEST(MockWindow, KeyDownWithCtrlToggled) {
322 std::function<void(
bool)>
callback) {
327 std::array<BYTE, 256> keyboard_state;
328 keyboard_state[VK_CONTROL] = 1;
329 SetKeyboardState(keyboard_state.data());
331 LPARAM lparam = CreateKeyEventLparam(30,
false,
false);
333 EXPECT_CALL(window, OnKey(65, 30, WM_KEYDOWN, 0,
false,
false, _))
335 .WillOnce(respond_false);
336 EXPECT_CALL(window, OnText(_)).Times(1);
339 Win32Message messages[] = {{WM_KEYDOWN, 65, lparam, kWmResultDontCheck},
340 {WM_CHAR, 65, lparam, kWmResultDontCheck}};
341 window.InjectMessageList(2, messages);
343 keyboard_state.fill(0);
344 SetKeyboardState(keyboard_state.data());
349 EXPECT_CALL(window, OnPaint()).Times(1);
350 window.InjectWindowMessage(WM_PAINT, 0, 0);
354 TEST(MockWindow, PointerHitTest) {
355 UINT32 pointer_id = 123;
356 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
357 auto text_input_manager = std::make_unique<MockTextInputManager>();
359 EXPECT_CALL(*windows_proc_table, GetPointerType(Eq(pointer_id), _))
361 .WillOnce([](UINT32 pointer_id, POINTER_INPUT_TYPE*
type) {
366 MockWindow window(std::move(windows_proc_table),
367 std::move(text_input_manager));
369 auto direct_manipulation =
370 std::make_unique<MockDirectManipulationOwner>(&window);
372 EXPECT_CALL(*direct_manipulation, SetContact).Times(0);
374 window.SetDirectManipulationOwner(std::move(direct_manipulation));
375 window.InjectWindowMessage(DM_POINTERHITTEST, MAKEWPARAM(pointer_id, 0), 0);
379 TEST(MockWindow, TouchPadHitTest) {
380 UINT32 pointer_id = 123;
381 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
382 auto text_input_manager = std::make_unique<MockTextInputManager>();
384 EXPECT_CALL(*windows_proc_table, GetPointerType(Eq(pointer_id), _))
386 .WillOnce([](UINT32 pointer_id, POINTER_INPUT_TYPE*
type) {
391 MockWindow window(std::move(windows_proc_table),
392 std::move(text_input_manager));
394 auto direct_manipulation =
395 std::make_unique<MockDirectManipulationOwner>(&window);
397 EXPECT_CALL(*direct_manipulation, SetContact(Eq(pointer_id))).Times(1);
399 window.SetDirectManipulationOwner(std::move(direct_manipulation));
400 window.InjectWindowMessage(DM_POINTERHITTEST, MAKEWPARAM(pointer_id, 0), 0);
407 TEST(MockWindow, UnknownPointerTypeSkipsDirectManipulation) {
408 UINT32 pointer_id = 123;
409 auto windows_proc_table = std::make_unique<MockWindowsProcTable>();
410 auto text_input_manager = std::make_unique<MockTextInputManager>();
412 EXPECT_CALL(*windows_proc_table, GetPointerType(Eq(pointer_id), _))
415 [](UINT32 pointer_id, POINTER_INPUT_TYPE*
type) {
return FALSE; });
417 MockWindow window(std::move(windows_proc_table),
418 std::move(text_input_manager));
420 auto direct_manipulation =
421 std::make_unique<MockDirectManipulationOwner>(&window);
423 EXPECT_CALL(*direct_manipulation, SetContact).Times(0);
425 window.SetDirectManipulationOwner(std::move(direct_manipulation));
426 window.InjectWindowMessage(DM_POINTERHITTEST, MAKEWPARAM(pointer_id, 0), 0);
430 TEST(MockWindow, DISABLED_GetObjectUia) {
432 bool uia_called =
false;
433 ON_CALL(window, OnGetObject)
434 .WillByDefault([&uia_called](UINT msg, WPARAM wpar, LPARAM lpar) {
435 #ifdef FLUTTER_ENGINE_USE_UIA
438 return static_cast<LRESULT
>(0);
440 EXPECT_CALL(window, OnGetObject).Times(1);
442 window.InjectWindowMessage(WM_GETOBJECT, 0, UiaRootObjectId);
444 EXPECT_TRUE(uia_called);
FlutterDesktopBinaryReply callback
enum flutter::testing::@104::KeyboardChange::Type type
TEST(AccessibilityBridgeWindows, GetParent)