1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "composer/key_event_util.h"
31 
32 #include <string>
33 
34 #include "base/util.h"
35 #include "composer/key_parser.h"
36 #include "protocol/commands.pb.h"
37 #include "testing/base/public/gunit.h"
38 
39 namespace mozc {
40 using commands::KeyEvent;
41 
42 namespace {
CompareKeyEvent(const char * expected_expr,const char * actual_expr,const KeyEvent & expected,const KeyEvent & actual)43 ::testing::AssertionResult CompareKeyEvent(const char *expected_expr,
44                                            const char *actual_expr,
45                                            const KeyEvent &expected,
46                                            const KeyEvent &actual) {
47   {  // Key code
48     const int expected_key_code =
49         (expected.has_key_code()) ? expected.key_code() : -1;
50     const int actual_key_code =
51         (actual.has_key_code()) ? actual.key_code() : -1;
52     if (expected_key_code != actual_key_code) {
53       const string expected_value = (expected_key_code == -1)
54           ? "None"
55           : Util::StringPrintf("%c (%d)", expected_key_code, expected_key_code);
56       const string actual_value = (actual_key_code == -1)
57           ? string("None")
58           : Util::StringPrintf("%c (%d)", actual_key_code, actual_key_code);
59       return ::testing::AssertionFailure() <<
60           "Key codes are not same\n" <<
61           "Expected: " << expected_value << "\n" <<
62           "Actual  : " << actual_value;
63     }
64   }
65 
66   {  // Special key
67     const int expected_special_key =
68         (expected.has_special_key()) ? expected.special_key() : -1;
69     const int actual_special_key =
70         (actual.has_special_key()) ? actual.special_key() : -1;
71     if (expected_special_key != actual_special_key) {
72       const string expected_value = (expected_special_key == -1)
73           ? "None" : std::to_string(expected_special_key);
74       const string actual_value = (actual_special_key == -1)
75           ? "None" : std::to_string(actual_special_key);
76       return ::testing::AssertionFailure() <<
77           "Special keys are not same\n" <<
78           "Expected: " << expected_value << "\n" <<
79           "Actual  : " << actual_value;
80     }
81   }
82 
83   {  // Modifier keys
84     const int expected_modifier_keys = KeyEventUtil::GetModifiers(expected);
85     const int actual_modifier_keys = KeyEventUtil::GetModifiers(actual);
86     if (expected_modifier_keys != actual_modifier_keys) {
87       return ::testing::AssertionFailure() <<
88           "Modifier keys are not same\n" <<
89           "Expected: " << expected_modifier_keys << "\n" <<
90           "Actual  : " << actual_modifier_keys;
91     }
92   }
93 
94   return ::testing::AssertionSuccess();
95 }
96 
97 #define EXPECT_EQ_KEY_EVENT(expected, actual) \
98   EXPECT_PRED_FORMAT2(CompareKeyEvent, expected, actual)
99 }  // namespace
100 
TEST(KeyEventUtilTest,GetModifiers)101 TEST(KeyEventUtilTest, GetModifiers) {
102   KeyEvent key_event;
103 
104   KeyParser::ParseKey("a", &key_event);
105   EXPECT_EQ(0, KeyEventUtil::GetModifiers(key_event));
106 
107   KeyParser::ParseKey("Alt", &key_event);
108   EXPECT_EQ(KeyEvent::ALT, KeyEventUtil::GetModifiers(key_event));
109 
110   KeyParser::ParseKey("Ctrl", &key_event);
111   EXPECT_EQ(KeyEvent::CTRL, KeyEventUtil::GetModifiers(key_event));
112 
113   KeyParser::ParseKey("Shift", &key_event);
114   EXPECT_EQ(KeyEvent::SHIFT, KeyEventUtil::GetModifiers(key_event));
115 
116   KeyParser::ParseKey("Caps", &key_event);
117   EXPECT_EQ(KeyEvent::CAPS, KeyEventUtil::GetModifiers(key_event));
118 
119   KeyParser::ParseKey("LeftAlt RightAlt", &key_event);
120   EXPECT_EQ((KeyEvent::ALT | KeyEvent::LEFT_ALT | KeyEvent::RIGHT_ALT),
121             KeyEventUtil::GetModifiers(key_event));
122 
123   KeyParser::ParseKey("LeftAlt Ctrl RightShift", &key_event);
124   EXPECT_EQ((KeyEvent::ALT | KeyEvent::LEFT_ALT | KeyEvent::CTRL |
125              KeyEvent::SHIFT | KeyEvent::RIGHT_SHIFT),
126             KeyEventUtil::GetModifiers(key_event));
127 }
128 
TEST(KeyEventUtilTest,GetKeyInformation)129 TEST(KeyEventUtilTest, GetKeyInformation) {
130   const char *kTestKeys[] = {
131     "a",
132     "Space",
133     "Shift",
134     "Shift a",
135     "Shift Space",
136     "Space a",
137     "LeftShift Space a",
138   };
139 
140   KeyEvent key_event;
141   uint64 output;
142 
143   for (size_t i = 0; i < arraysize(kTestKeys); ++i) {
144     SCOPED_TRACE(kTestKeys[i]);
145     KeyParser::ParseKey(kTestKeys[i], &key_event);
146     ASSERT_TRUE(KeyEventUtil::GetKeyInformation(key_event, &output));
147 
148     uint64 expected = 0;
149     if (key_event.has_key_code()) {
150       expected |= static_cast<uint64>(key_event.key_code());
151     }
152     if (key_event.has_special_key()) {
153       expected |= static_cast<uint64>(key_event.special_key()) << 32;
154     }
155     expected |=
156         static_cast<uint64>(KeyEventUtil::GetModifiers(key_event)) << 48;
157 
158     EXPECT_EQ(expected, output);
159   }
160 
161   const uint32 kEscapeKeyCode = 27;
162   key_event.Clear();
163   key_event.set_key_code(kEscapeKeyCode);
164   // Escape key should not set on key_code field.
165   EXPECT_FALSE(KeyEventUtil::GetKeyInformation(key_event, &output));
166 }
167 
TEST(KeyEventUtilTest,NormalizeModifiers)168 TEST(KeyEventUtilTest, NormalizeModifiers) {
169   KeyEvent key_event;
170   KeyEvent normalized_key_event;
171 
172   {  // Removes caps
173     KeyParser::ParseKey("CAPS H", &key_event);
174     ASSERT_EQ(1, key_event.modifier_keys_size());
175     ASSERT_EQ(KeyEvent::CAPS, KeyEventUtil::GetModifiers(key_event));
176     ASSERT_EQ('H', key_event.key_code());
177 
178     KeyEventUtil::NormalizeModifiers(key_event, &normalized_key_event);
179     EXPECT_EQ(0, normalized_key_event.modifier_keys_size());
180     EXPECT_EQ('h', normalized_key_event.key_code());
181   }
182 
183   {  // Removes left_shift
184     KeyParser::ParseKey("LeftShift", &key_event);
185     ASSERT_EQ(2, key_event.modifier_keys_size());
186     ASSERT_EQ((KeyEvent::SHIFT | KeyEvent::LEFT_SHIFT),
187               KeyEventUtil::GetModifiers(key_event));
188 
189     KeyEventUtil::NormalizeModifiers(key_event, &normalized_key_event);
190     EXPECT_EQ(1, normalized_key_event.modifier_keys_size());
191     ASSERT_EQ(KeyEvent::SHIFT,
192               KeyEventUtil::GetModifiers(normalized_key_event));
193   }
194 
195   {  // Removes caps and left_shift
196     KeyParser::ParseKey("CAPS LeftShift H", &key_event);
197     ASSERT_EQ(3, key_event.modifier_keys_size());
198     ASSERT_EQ((KeyEvent::CAPS | KeyEvent::SHIFT | KeyEvent::LEFT_SHIFT),
199               KeyEventUtil::GetModifiers(key_event));
200 
201     ASSERT_EQ('H', key_event.key_code());
202 
203     KeyEventUtil::NormalizeModifiers(key_event, &normalized_key_event);
204     EXPECT_EQ(1, normalized_key_event.modifier_keys_size());
205     EXPECT_EQ(KeyEvent::SHIFT,
206               KeyEventUtil::GetModifiers(normalized_key_event));
207     EXPECT_EQ('h', normalized_key_event.key_code());
208   }
209 }
210 
TEST(KeyEventUtilTest,NormalizeNumpadKey)211 TEST(KeyEventUtilTest, NormalizeNumpadKey) {
212   const struct NormalizeNumpadKeyTestData {
213     const char *from;
214     const char *to;
215   } kNormalizeNumpadKeyTestData[] = {
216     { "a",             "a" },
217     { "Shift",         "Shift" },
218     { "Caps",          "Caps" },
219     { "Enter",         "Enter" },
220     { "Shift Caps a",  "Shift Caps a" },
221     { "NUMPAD0",       "0" },
222     { "NUMPAD9",       "9" },
223     { "MULTIPLY",      "*" },
224     { "SEPARATOR",     "Enter" },
225     { "EQUALS",        "=" },
226     { "Ctrl NUMPAD0",  "Ctrl 0" },
227     { "NUMPAD0 a",     "0" },
228   };
229 
230   for (size_t i = 0; i < arraysize(kNormalizeNumpadKeyTestData); ++i) {
231     const NormalizeNumpadKeyTestData &data = kNormalizeNumpadKeyTestData[i];
232     SCOPED_TRACE(data.from);
233 
234     KeyEvent key_event_from, key_event_to, key_event_normalized;
235     KeyParser::ParseKey(data.from, &key_event_from);
236     KeyParser::ParseKey(data.to, &key_event_to);
237     KeyEventUtil::NormalizeNumpadKey(key_event_from, &key_event_normalized);
238     EXPECT_EQ_KEY_EVENT(key_event_to, key_event_normalized);
239   }
240 }
241 
TEST(KeyEventUtilTest,MaybeGetKeyStub)242 TEST(KeyEventUtilTest, MaybeGetKeyStub) {
243   KeyEvent key_event;
244   KeyInformation key;
245 
246   KeyParser::ParseKey("Shift", &key_event);
247   EXPECT_FALSE(KeyEventUtil::MaybeGetKeyStub(key_event, &key));
248 
249   KeyParser::ParseKey("Space", &key_event);
250   EXPECT_FALSE(KeyEventUtil::MaybeGetKeyStub(key_event, &key));
251 
252   const uint32 kEscapeKeyCode = 27;
253   key_event.Clear();
254   key_event.set_key_code(kEscapeKeyCode);
255   EXPECT_FALSE(KeyEventUtil::MaybeGetKeyStub(key_event, &key));
256 
257   KeyParser::ParseKey("a", &key_event);
258   EXPECT_TRUE(KeyEventUtil::MaybeGetKeyStub(key_event, &key));
259   EXPECT_EQ(static_cast<KeyInformation>(KeyEvent::TEXT_INPUT) << 32, key);
260 }
261 
TEST(KeyEventUtilTest,RemvoeModifiers)262 TEST(KeyEventUtilTest, RemvoeModifiers) {
263   const struct RemoveModifiersTestData {
264     const char *input;
265     const char *remove;
266     const char *output;
267   } kRemoveModifiersTestData[] = {
268     {
269       "",
270       "",
271       "",
272     }, {
273       "Ctrl Shift LeftAlt Caps",
274       "Ctrl Shift LeftAlt Caps",
275       "",
276     }, {
277       "Ctrl Shift LeftAlt Caps",
278       "Shift Caps",
279       "Ctrl LeftAlt",
280     }, {
281       "Ctrl Shift LeftAlt Caps",
282       "Alt",
283       "Ctrl Shift Caps",
284     }, {
285       "",
286       "Ctrl Shift LeftAlt Caps",
287       "",
288     },
289   };
290 
291   for (size_t i = 0; i < arraysize(kRemoveModifiersTestData); ++i) {
292     SCOPED_TRACE(Util::StringPrintf("index = %d", static_cast<int>(i)));
293     const RemoveModifiersTestData &data = kRemoveModifiersTestData[i];
294 
295     KeyEvent input, remove, output;
296     KeyParser::ParseKey(data.input, &input);
297     KeyParser::ParseKey(data.remove, &remove);
298     KeyParser::ParseKey(data.output, &output);
299     const uint32 remove_modifiers = KeyEventUtil::GetModifiers(remove);
300 
301     KeyEvent removed_key_event;
302     KeyEventUtil::RemoveModifiers(input, remove_modifiers, &removed_key_event);
303     EXPECT_EQ_KEY_EVENT(output, removed_key_event);
304   }
305 }
306 
TEST(KeyEventUtilTest,HasModifiers)307 TEST(KeyEventUtilTest, HasModifiers) {
308   EXPECT_TRUE(KeyEventUtil::HasAlt(KeyEvent::ALT));
309   EXPECT_TRUE(KeyEventUtil::HasAlt(KeyEvent::LEFT_ALT));
310   EXPECT_TRUE(KeyEventUtil::HasAlt(KeyEvent::ALT | KeyEvent::CTRL));
311   EXPECT_FALSE(KeyEventUtil::HasAlt(0));
312   EXPECT_FALSE(KeyEventUtil::HasAlt(KeyEvent::CTRL));
313   EXPECT_FALSE(KeyEventUtil::HasAlt(KeyEvent::SHIFT));
314 
315   EXPECT_TRUE(KeyEventUtil::HasCtrl(KeyEvent::CTRL));
316   EXPECT_TRUE(KeyEventUtil::HasCtrl(KeyEvent::LEFT_CTRL));
317   EXPECT_TRUE(KeyEventUtil::HasCtrl(KeyEvent::CTRL | KeyEvent::SHIFT));
318   EXPECT_FALSE(KeyEventUtil::HasCtrl(0));
319   EXPECT_FALSE(KeyEventUtil::HasCtrl(KeyEvent::ALT));
320   EXPECT_FALSE(KeyEventUtil::HasCtrl(KeyEvent::SHIFT));
321 
322   EXPECT_TRUE(KeyEventUtil::HasShift(KeyEvent::SHIFT));
323   EXPECT_TRUE(KeyEventUtil::HasShift(KeyEvent::LEFT_SHIFT));
324   EXPECT_TRUE(KeyEventUtil::HasShift(KeyEvent::SHIFT | KeyEvent::ALT));
325   EXPECT_FALSE(KeyEventUtil::HasShift(0));
326   EXPECT_FALSE(KeyEventUtil::HasShift(KeyEvent::ALT));
327   EXPECT_FALSE(KeyEventUtil::HasShift(KeyEvent::CTRL));
328 
329   EXPECT_TRUE(KeyEventUtil::HasCaps(KeyEvent::CAPS));
330   EXPECT_TRUE(KeyEventUtil::HasCaps(KeyEvent::CAPS | KeyEvent::ALT));
331   EXPECT_FALSE(KeyEventUtil::HasCaps(0));
332   EXPECT_FALSE(KeyEventUtil::HasCaps(KeyEvent::CTRL));
333 }
334 
TEST(KeyEventUtilTest,IsModifiers)335 TEST(KeyEventUtilTest, IsModifiers) {
336   const struct IsModifiersTestData {
337     uint32 modifiers;
338     bool is_alt;
339     bool is_ctrl;
340     bool is_shift;
341     bool is_alt_ctrl;
342     bool is_alt_shift;
343     bool is_ctrl_shift;
344     bool is_alt_ctrl_shift;
345   } kIsModifiersTestData[] = {
346     {
347       0,
348       false, false, false, false, false, false, false
349     }, {
350       KeyEvent::ALT,
351       true, false, false, false, false, false, false,
352     }, {
353       KeyEvent::CTRL,
354       false, true, false, false, false, false, false,
355     }, {
356       KeyEvent::SHIFT,
357       false, false, true, false, false, false, false,
358     }, {
359       KeyEvent::ALT | KeyEvent::CTRL,
360       false, false, false, true, false, false, false,
361     }, {
362       KeyEvent::ALT | KeyEvent::SHIFT,
363       false, false, false, false, true, false, false,
364     }, {
365       KeyEvent::CTRL | KeyEvent::SHIFT,
366       false, false, false, false, false, true, false,
367     }, {
368       KeyEvent::ALT | KeyEvent::CTRL | KeyEvent::SHIFT,
369       false, false, false, false, false, false, true,
370     }, {
371       KeyEvent::LEFT_ALT,
372       true, false, false, false, false, false, false,
373     }, {
374       KeyEvent::ALT | KeyEvent::LEFT_ALT | KeyEvent::RIGHT_ALT,
375       true, false, false, false, false, false, false,
376     }, {
377       KeyEvent::CAPS,
378       false, false, false, false, false, false, false,
379     }, {
380       KeyEvent::ALT | KeyEvent::CAPS,
381       true, false, false, false, false, false, false,
382     },
383   };
384 
385   for (size_t i = 0; i < arraysize(kIsModifiersTestData); ++i) {
386     const IsModifiersTestData &data = kIsModifiersTestData[i];
387     SCOPED_TRACE(Util::StringPrintf("index: %d", static_cast<int>(i)));
388 
389     EXPECT_EQ(data.is_alt, KeyEventUtil::IsAlt(data.modifiers));
390     EXPECT_EQ(data.is_ctrl, KeyEventUtil::IsCtrl(data.modifiers));
391     EXPECT_EQ(data.is_shift, KeyEventUtil::IsShift(data.modifiers));
392     EXPECT_EQ(data.is_alt_ctrl, KeyEventUtil::IsAltCtrl(data.modifiers));
393     EXPECT_EQ(data.is_alt_shift, KeyEventUtil::IsAltShift(data.modifiers));
394     EXPECT_EQ(data.is_ctrl_shift, KeyEventUtil::IsCtrlShift(data.modifiers));
395     EXPECT_EQ(data.is_alt_ctrl_shift,
396               KeyEventUtil::IsAltCtrlShift(data.modifiers));
397   }
398 }
399 
TEST(KeyEventUtilTest,IsLowerUpperAlphabet)400 TEST(KeyEventUtilTest, IsLowerUpperAlphabet) {
401   const struct IsLowerUpperAlphabetTestData {
402     const char *key;
403     bool is_lower;
404     bool is_upper;
405   } kIsLowerUpperAlphabetTestData[] = {
406     { "a",            true,  false },
407     { "A",            false, true },
408     { "Shift a",      false, true },
409     { "Shift A",      true,  false },
410     { "Shift Caps a", true,  false },
411     { "Shift Caps A", false, true },
412     { "0",            false, false },
413     { "Shift",        false, false },
414     { "Caps",         false, false },
415     { "Space",        false, false },
416   };
417 
418   for (size_t i = 0; i < arraysize(kIsLowerUpperAlphabetTestData); ++i) {
419     const IsLowerUpperAlphabetTestData &data = kIsLowerUpperAlphabetTestData[i];
420     SCOPED_TRACE(data.key);
421     KeyEvent key_event;
422     KeyParser::ParseKey(data.key, &key_event);
423     EXPECT_EQ(data.is_lower, KeyEventUtil::IsLowerAlphabet(key_event));
424     EXPECT_EQ(data.is_upper, KeyEventUtil::IsUpperAlphabet(key_event));
425   }
426 }
427 
TEST(KeyEventUtilTest,IsNumpadKey)428 TEST(KeyEventUtilTest, IsNumpadKey) {
429   const struct IsNumpadKeyTestData {
430     const char *key;
431     bool is_numpad_key;
432   } kIsNumpadKeyTestData[] = {
433     { "a",            false },
434     { "A",            false },
435     { "Shift",        false },
436     { "Shift a",      false },
437     { "0",            false },
438     { "EISU",         false },
439     { "NUMPAD0",      true },
440     { "NUMPAD9",      true },
441     { "MULTIPLY",     true },
442     { "EQUALS",       true },
443     { "COMMA",        true },
444     { "TEXTINPUT",    false },
445   };
446 
447   for (size_t i = 0; i < arraysize(kIsNumpadKeyTestData); ++i) {
448     const IsNumpadKeyTestData &data = kIsNumpadKeyTestData[i];
449     SCOPED_TRACE(data.key);
450     KeyEvent key_event;
451     KeyParser::ParseKey(data.key, &key_event);
452     EXPECT_EQ(data.is_numpad_key, KeyEventUtil::IsNumpadKey(key_event));
453   }
454 }
455 
456 }  // namespace mozc
457