test_keypress.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. /* Copyright 2017 Fred Sundvik
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "keycode.h"
  17. #include "test_common.hpp"
  18. using testing::_;
  19. using testing::InSequence;
  20. class KeyPress : public TestFixture {};
  21. TEST_F(KeyPress, SendKeyboardIsNotCalledWhenNoKeyIsPressed) {
  22. TestDriver driver;
  23. EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0);
  24. keyboard_task();
  25. }
  26. TEST_F(KeyPress, CorrectKeyIsReportedWhenPressed) {
  27. TestDriver driver;
  28. auto key = KeymapKey(0, 0, 0, KC_A);
  29. set_keymap({key});
  30. key.press();
  31. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key.report_code)));
  32. keyboard_task();
  33. key.release();
  34. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  35. keyboard_task();
  36. }
  37. TEST_F(KeyPress, ANonMappedKeyDoesNothing) {
  38. TestDriver driver;
  39. auto key = KeymapKey(0, 0, 0, KC_NO);
  40. set_keymap({key});
  41. key.press();
  42. EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0);
  43. keyboard_task();
  44. keyboard_task();
  45. }
  46. TEST_F(KeyPress, CorrectKeysAreReportedWhenTwoKeysArePressed) {
  47. TestDriver driver;
  48. auto key_b = KeymapKey(0, 0, 0, KC_B);
  49. auto key_c = KeymapKey(0, 1, 1, KC_C);
  50. set_keymap({key_b, key_c});
  51. key_b.press();
  52. key_c.press();
  53. // Note that QMK only processes one key at a time
  54. // See issue #1476 for more information
  55. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_b.report_code)));
  56. keyboard_task();
  57. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_b.report_code, key_c.report_code)));
  58. keyboard_task();
  59. key_b.release();
  60. key_c.release();
  61. // Note that the first key released is the first one in the matrix order
  62. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_c.report_code)));
  63. keyboard_task();
  64. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  65. keyboard_task();
  66. }
  67. TEST_F(KeyPress, LeftShiftIsReportedCorrectly) {
  68. TestDriver driver;
  69. auto key_a = KeymapKey(0, 0, 0, KC_A);
  70. auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT);
  71. set_keymap({key_a, key_lsft});
  72. key_lsft.press();
  73. key_a.press();
  74. // Unfortunately modifiers are also processed in the wrong order
  75. // See issue #1476 for more information
  76. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_a.report_code)));
  77. keyboard_task();
  78. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_a.report_code, key_lsft.report_code)));
  79. keyboard_task();
  80. key_a.release();
  81. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lsft.report_code)));
  82. keyboard_task();
  83. key_lsft.release();
  84. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  85. keyboard_task();
  86. }
  87. TEST_F(KeyPress, PressLeftShiftAndControl) {
  88. TestDriver driver;
  89. auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT);
  90. auto key_lctrl = KeymapKey(0, 5, 0, KC_LEFT_CTRL);
  91. set_keymap({key_lctrl, key_lsft});
  92. key_lsft.press();
  93. key_lctrl.press();
  94. // Unfortunately modifiers are also processed in the wrong order
  95. // See issue #1476 for more information
  96. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lsft.report_code)));
  97. keyboard_task();
  98. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lsft.report_code, key_lctrl.report_code)));
  99. keyboard_task();
  100. key_lsft.release();
  101. key_lctrl.release();
  102. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lctrl.report_code)));
  103. keyboard_task();
  104. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  105. keyboard_task();
  106. }
  107. TEST_F(KeyPress, LeftAndRightShiftCanBePressedAtTheSameTime) {
  108. TestDriver driver;
  109. auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT);
  110. auto key_rsft = KeymapKey(0, 4, 0, KC_RIGHT_SHIFT);
  111. set_keymap({key_rsft, key_lsft});
  112. key_lsft.press();
  113. key_rsft.press();
  114. // Unfortunately modifiers are also processed in the wrong order
  115. // See issue #1476 for more information
  116. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lsft.report_code)));
  117. keyboard_task();
  118. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_lsft.report_code, key_rsft.report_code)));
  119. keyboard_task();
  120. key_lsft.release();
  121. key_rsft.release();
  122. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_rsft.report_code)));
  123. keyboard_task();
  124. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  125. keyboard_task();
  126. }
  127. TEST_F(KeyPress, RightShiftLeftControlAndCharWithTheSameKey) {
  128. TestDriver driver;
  129. auto combo_key = KeymapKey(0, 0, 0, RSFT(LCTL(KC_O)));
  130. set_keymap({combo_key});
  131. // BUG: The press is split into two reports
  132. // BUG: It reports RSFT instead of LSFT
  133. // See issue #524 for more information
  134. // The underlying cause is that we use only one bit to represent the right hand
  135. // modifiers.
  136. combo_key.press();
  137. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RIGHT_SHIFT, KC_RIGHT_CTRL)));
  138. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RIGHT_SHIFT, KC_RIGHT_CTRL, KC_O)));
  139. keyboard_task();
  140. combo_key.release();
  141. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RIGHT_SHIFT, KC_RIGHT_CTRL)));
  142. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  143. keyboard_task();
  144. }
  145. TEST_F(KeyPress, PressPlusEqualReleaseBeforePress) {
  146. TestDriver driver;
  147. InSequence s;
  148. auto key_plus = KeymapKey(0, 1, 1, KC_PLUS);
  149. auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL);
  150. set_keymap({key_plus, key_eql});
  151. key_plus.press();
  152. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  153. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_EQUAL)));
  154. run_one_scan_loop();
  155. testing::Mock::VerifyAndClearExpectations(&driver);
  156. key_plus.release();
  157. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  158. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  159. run_one_scan_loop();
  160. testing::Mock::VerifyAndClearExpectations(&driver);
  161. key_eql.press();
  162. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(key_eql.report_code)));
  163. run_one_scan_loop();
  164. testing::Mock::VerifyAndClearExpectations(&driver);
  165. key_eql.release();
  166. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  167. run_one_scan_loop();
  168. testing::Mock::VerifyAndClearExpectations(&driver);
  169. }
  170. TEST_F(KeyPress, PressPlusEqualDontReleaseBeforePress) {
  171. TestDriver driver;
  172. InSequence s;
  173. auto key_plus = KeymapKey(0, 1, 1, KC_PLUS);
  174. auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL);
  175. set_keymap({key_plus, key_eql});
  176. key_plus.press();
  177. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  178. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_EQUAL)));
  179. run_one_scan_loop();
  180. testing::Mock::VerifyAndClearExpectations(&driver);
  181. key_eql.press();
  182. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  183. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_EQUAL)));
  184. run_one_scan_loop();
  185. testing::Mock::VerifyAndClearExpectations(&driver);
  186. key_plus.release();
  187. // BUG: Should really still return KC_EQUAL, but this is fine too
  188. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1);
  189. run_one_scan_loop();
  190. testing::Mock::VerifyAndClearExpectations(&driver);
  191. key_eql.release();
  192. EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0);
  193. run_one_scan_loop();
  194. testing::Mock::VerifyAndClearExpectations(&driver);
  195. }
  196. TEST_F(KeyPress, PressEqualPlusReleaseBeforePress) {
  197. TestDriver driver;
  198. InSequence s;
  199. auto key_plus = KeymapKey(0, 1, 1, KC_PLUS);
  200. auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL);
  201. set_keymap({key_plus, key_eql});
  202. key_eql.press();
  203. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_EQUAL)));
  204. run_one_scan_loop();
  205. testing::Mock::VerifyAndClearExpectations(&driver);
  206. key_eql.release();
  207. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  208. run_one_scan_loop();
  209. testing::Mock::VerifyAndClearExpectations(&driver);
  210. key_plus.press();
  211. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  212. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_EQUAL)));
  213. run_one_scan_loop();
  214. testing::Mock::VerifyAndClearExpectations(&driver);
  215. key_plus.release();
  216. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  217. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  218. run_one_scan_loop();
  219. testing::Mock::VerifyAndClearExpectations(&driver);
  220. }
  221. TEST_F(KeyPress, PressEqualPlusDontReleaseBeforePress) {
  222. TestDriver driver;
  223. InSequence s;
  224. auto key_plus = KeymapKey(0, 1, 1, KC_PLUS);
  225. auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL);
  226. set_keymap({key_plus, key_eql});
  227. key_eql.press();
  228. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_EQUAL)));
  229. run_one_scan_loop();
  230. testing::Mock::VerifyAndClearExpectations(&driver);
  231. key_plus.press();
  232. // BUG: The sequence is a bit strange, but it works, the end result is that
  233. // KC_PLUS is sent
  234. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_EQUAL)));
  235. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  236. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT, KC_EQUAL)));
  237. run_one_scan_loop();
  238. testing::Mock::VerifyAndClearExpectations(&driver);
  239. key_eql.release();
  240. // I guess it's fine to still report shift here
  241. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LEFT_SHIFT)));
  242. run_one_scan_loop();
  243. testing::Mock::VerifyAndClearExpectations(&driver);
  244. key_plus.release();
  245. EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport()));
  246. run_one_scan_loop();
  247. testing::Mock::VerifyAndClearExpectations(&driver);
  248. }