keyboard stuff
at master 292 lines 8.1 kB view raw
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 17#include "keycode.h" 18#include "test_common.hpp" 19 20using testing::_; 21using testing::InSequence; 22 23class KeyPress : public TestFixture {}; 24 25TEST_F(KeyPress, SendKeyboardIsNotCalledWhenNoKeyIsPressed) { 26 TestDriver driver; 27 EXPECT_NO_REPORT(driver); 28 keyboard_task(); 29} 30 31TEST_F(KeyPress, CorrectKeyIsReportedWhenPressed) { 32 TestDriver driver; 33 auto key = KeymapKey(0, 0, 0, KC_A); 34 35 set_keymap({key}); 36 37 key.press(); 38 EXPECT_REPORT(driver, (key.report_code)); 39 keyboard_task(); 40 41 key.release(); 42 EXPECT_EMPTY_REPORT(driver); 43 keyboard_task(); 44} 45 46TEST_F(KeyPress, ANonMappedKeyDoesNothing) { 47 TestDriver driver; 48 auto key = KeymapKey(0, 0, 0, KC_NO); 49 50 set_keymap({key}); 51 52 key.press(); 53 EXPECT_NO_REPORT(driver); 54 keyboard_task(); 55 keyboard_task(); 56} 57 58TEST_F(KeyPress, CorrectKeysAreReportedWhenTwoKeysArePressed) { 59 TestDriver driver; 60 auto key_b = KeymapKey(0, 0, 0, KC_B); 61 auto key_c = KeymapKey(0, 1, 1, KC_C); 62 63 set_keymap({key_b, key_c}); 64 65 key_b.press(); 66 key_c.press(); 67 EXPECT_REPORT(driver, (key_b.report_code)); 68 EXPECT_REPORT(driver, (key_b.report_code, key_c.report_code)); 69 keyboard_task(); 70 71 key_b.release(); 72 key_c.release(); 73 // Note that the first key released is the first one in the matrix order 74 EXPECT_REPORT(driver, (key_c.report_code)); 75 EXPECT_EMPTY_REPORT(driver); 76 keyboard_task(); 77} 78 79TEST_F(KeyPress, LeftShiftIsReportedCorrectly) { 80 TestDriver driver; 81 auto key_a = KeymapKey(0, 0, 0, KC_A); 82 auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT); 83 84 set_keymap({key_a, key_lsft}); 85 86 key_lsft.press(); 87 key_a.press(); 88 89 EXPECT_REPORT(driver, (key_a.report_code)); 90 EXPECT_REPORT(driver, (key_a.report_code, key_lsft.report_code)); 91 keyboard_task(); 92 93 key_a.release(); 94 EXPECT_REPORT(driver, (key_lsft.report_code)); 95 keyboard_task(); 96 97 key_lsft.release(); 98 EXPECT_EMPTY_REPORT(driver); 99 keyboard_task(); 100} 101 102TEST_F(KeyPress, PressLeftShiftAndControl) { 103 TestDriver driver; 104 auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT); 105 auto key_lctrl = KeymapKey(0, 5, 0, KC_LEFT_CTRL); 106 107 set_keymap({key_lctrl, key_lsft}); 108 109 key_lsft.press(); 110 key_lctrl.press(); 111 112 EXPECT_REPORT(driver, (key_lsft.report_code)); 113 EXPECT_REPORT(driver, (key_lsft.report_code, key_lctrl.report_code)); 114 keyboard_task(); 115 116 key_lsft.release(); 117 key_lctrl.release(); 118 119 EXPECT_REPORT(driver, (key_lctrl.report_code)); 120 EXPECT_EMPTY_REPORT(driver); 121 keyboard_task(); 122} 123 124TEST_F(KeyPress, LeftAndRightShiftCanBePressedAtTheSameTime) { 125 TestDriver driver; 126 auto key_lsft = KeymapKey(0, 3, 0, KC_LEFT_SHIFT); 127 auto key_rsft = KeymapKey(0, 4, 0, KC_RIGHT_SHIFT); 128 129 set_keymap({key_rsft, key_lsft}); 130 131 key_lsft.press(); 132 key_rsft.press(); 133 EXPECT_REPORT(driver, (key_lsft.report_code)); 134 EXPECT_REPORT(driver, (key_lsft.report_code, key_rsft.report_code)); 135 keyboard_task(); 136 137 key_lsft.release(); 138 key_rsft.release(); 139 EXPECT_REPORT(driver, (key_rsft.report_code)); 140 EXPECT_EMPTY_REPORT(driver); 141 keyboard_task(); 142} 143 144TEST_F(KeyPress, RightShiftLeftControlAndCharWithTheSameKey) { 145 TestDriver driver; 146 auto combo_key = KeymapKey(0, 0, 0, RSFT(LCTL(KC_O))); 147 148 set_keymap({combo_key}); 149 150 // BUG: The press is split into two reports 151 // BUG: It reports RSFT instead of LSFT 152 // See issue #524 for more information 153 // The underlying cause is that we use only one bit to represent the right hand 154 // modifiers. 155 combo_key.press(); 156 EXPECT_REPORT(driver, (KC_RIGHT_SHIFT, KC_RIGHT_CTRL)); 157 EXPECT_REPORT(driver, (KC_RIGHT_SHIFT, KC_RIGHT_CTRL, KC_O)); 158 keyboard_task(); 159 160 combo_key.release(); 161 EXPECT_REPORT(driver, (KC_RIGHT_SHIFT, KC_RIGHT_CTRL)); 162 EXPECT_EMPTY_REPORT(driver); 163 keyboard_task(); 164} 165 166TEST_F(KeyPress, PressPlusEqualReleaseBeforePress) { 167 TestDriver driver; 168 InSequence s; 169 auto key_plus = KeymapKey(0, 1, 1, KC_PLUS); 170 auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL); 171 172 set_keymap({key_plus, key_eql}); 173 174 key_plus.press(); 175 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 176 EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_EQUAL)); 177 run_one_scan_loop(); 178 VERIFY_AND_CLEAR(driver); 179 180 key_plus.release(); 181 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 182 EXPECT_EMPTY_REPORT(driver); 183 run_one_scan_loop(); 184 VERIFY_AND_CLEAR(driver); 185 186 key_eql.press(); 187 EXPECT_REPORT(driver, (key_eql.report_code)); 188 run_one_scan_loop(); 189 VERIFY_AND_CLEAR(driver); 190 191 key_eql.release(); 192 EXPECT_EMPTY_REPORT(driver); 193 run_one_scan_loop(); 194 VERIFY_AND_CLEAR(driver); 195} 196 197TEST_F(KeyPress, PressPlusEqualDontReleaseBeforePress) { 198 TestDriver driver; 199 InSequence s; 200 auto key_plus = KeymapKey(0, 1, 1, KC_PLUS); 201 auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL); 202 203 set_keymap({key_plus, key_eql}); 204 205 key_plus.press(); 206 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 207 EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_EQUAL)); 208 run_one_scan_loop(); 209 VERIFY_AND_CLEAR(driver); 210 211 key_eql.press(); 212 EXPECT_EMPTY_REPORT(driver); 213 EXPECT_REPORT(driver, (KC_EQUAL)); 214 run_one_scan_loop(); 215 VERIFY_AND_CLEAR(driver); 216 217 key_plus.release(); 218 // BUG: Should really still return KC_EQUAL, but this is fine too 219 EXPECT_EMPTY_REPORT(driver); 220 run_one_scan_loop(); 221 VERIFY_AND_CLEAR(driver); 222 223 key_eql.release(); 224 EXPECT_NO_REPORT(driver); 225 run_one_scan_loop(); 226 VERIFY_AND_CLEAR(driver); 227} 228 229TEST_F(KeyPress, PressEqualPlusReleaseBeforePress) { 230 TestDriver driver; 231 InSequence s; 232 auto key_plus = KeymapKey(0, 1, 1, KC_PLUS); 233 auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL); 234 235 set_keymap({key_plus, key_eql}); 236 237 key_eql.press(); 238 EXPECT_REPORT(driver, (KC_EQUAL)); 239 run_one_scan_loop(); 240 VERIFY_AND_CLEAR(driver); 241 242 key_eql.release(); 243 EXPECT_EMPTY_REPORT(driver); 244 run_one_scan_loop(); 245 VERIFY_AND_CLEAR(driver); 246 247 key_plus.press(); 248 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 249 EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_EQUAL)); 250 run_one_scan_loop(); 251 VERIFY_AND_CLEAR(driver); 252 253 key_plus.release(); 254 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 255 EXPECT_EMPTY_REPORT(driver); 256 run_one_scan_loop(); 257 VERIFY_AND_CLEAR(driver); 258} 259 260TEST_F(KeyPress, PressEqualPlusDontReleaseBeforePress) { 261 TestDriver driver; 262 InSequence s; 263 auto key_plus = KeymapKey(0, 1, 1, KC_PLUS); 264 auto key_eql = KeymapKey(0, 0, 1, KC_EQUAL); 265 266 set_keymap({key_plus, key_eql}); 267 268 key_eql.press(); 269 EXPECT_REPORT(driver, (KC_EQUAL)); 270 run_one_scan_loop(); 271 VERIFY_AND_CLEAR(driver); 272 273 key_plus.press(); 274 // BUG: The sequence is a bit strange, but it works, the end result is that 275 // KC_PLUS is sent 276 EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_EQUAL)); 277 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 278 EXPECT_REPORT(driver, (KC_LEFT_SHIFT, KC_EQUAL)); 279 run_one_scan_loop(); 280 VERIFY_AND_CLEAR(driver); 281 282 key_eql.release(); 283 // I guess it's fine to still report shift here 284 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)); 285 run_one_scan_loop(); 286 VERIFY_AND_CLEAR(driver); 287 288 key_plus.release(); 289 EXPECT_EMPTY_REPORT(driver); 290 run_one_scan_loop(); 291 VERIFY_AND_CLEAR(driver); 292}