at master 26 kB view raw
1// Copyright 2023 Google LLC 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 <functional> 17 18#include "keyboard_report_util.hpp" 19#include "keycode.h" 20#include "test_common.hpp" 21#include "test_fixture.hpp" 22#include "test_keymap_key.hpp" 23 24using ::testing::AnyNumber; 25using ::testing::AnyOf; 26using ::testing::InSequence; 27 28#define FOO_MACRO SAFE_RANGE 29 30namespace { 31 32bool process_record_user_default(uint16_t keycode, keyrecord_t* record) { 33 return true; 34} 35 36bool remember_last_key_user_default(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) { 37 return true; 38} 39 40// Indirection so that process_record_user() and remember_last_key_user() 41// can be replaced with other functions in the test cases below. 42std::function<bool(uint16_t, keyrecord_t*)> process_record_user_fun = process_record_user_default; 43std::function<bool(uint16_t, keyrecord_t*, uint8_t*)> remember_last_key_user_fun = remember_last_key_user_default; 44 45extern "C" bool process_record_user(uint16_t keycode, keyrecord_t* record) { 46 return process_record_user_fun(keycode, record); 47} 48extern "C" bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) { 49 return remember_last_key_user_fun(keycode, record, remembered_mods); 50} 51 52class RepeatKey : public TestFixture { 53 public: 54 bool process_record_user_was_called_; 55 56 void SetUp() override { 57 autoshift_disable(); 58 process_record_user_fun = process_record_user_default; 59 remember_last_key_user_fun = remember_last_key_user_default; 60 } 61 62 void ExpectProcessRecordUserCalledWith(bool expected_press, uint16_t expected_keycode, int8_t expected_repeat_key_count) { 63 process_record_user_was_called_ = false; 64 process_record_user_fun = [=](uint16_t keycode, keyrecord_t* record) { 65 EXPECT_EQ(record->event.pressed, expected_press); 66 EXPECT_KEYCODE_EQ(keycode, expected_keycode); 67 EXPECT_EQ(get_repeat_key_count(), expected_repeat_key_count); 68 // Tests below use this to verify process_record_user() was called. 69 process_record_user_was_called_ = true; 70 return true; 71 }; 72 } 73 74 // Expects that the characters of `s` are sent. 75 // NOTE: This implementation is limited to chars a-z, A-Z. 76 void ExpectString(TestDriver& driver, const std::string& s) { 77 InSequence seq; 78 for (int c : s) { 79 switch (c) { 80 case 'a' ... 'z': { // Lowercase letter. 81 uint16_t keycode = c - ('a' - KC_A); 82 EXPECT_REPORT(driver, (keycode)); 83 } break; 84 85 case 'A' ... 'Z': { // Capital letter = KC_LSFT + letter key. 86 uint16_t keycode = c - ('A' - KC_A); 87 EXPECT_REPORT(driver, (KC_LSFT, keycode)); 88 } break; 89 } 90 } 91 } 92}; 93 94// Tests that "A, Repeat, Repeat, B, Repeat" produces "aaabb". 95TEST_F(RepeatKey, Basic) { 96 TestDriver driver; 97 KeymapKey key_a(0, 0, 0, KC_A); 98 KeymapKey key_b(0, 1, 0, KC_B); 99 KeymapKey key_repeat(0, 2, 0, QK_REP); 100 set_keymap({key_a, key_b, key_repeat}); 101 102 // Allow any number of empty reports. 103 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 104 ExpectString(driver, "aaabb"); 105 106 // When KC_A is pressed, process_record_user() should be called 107 // with a press event with keycode == KC_A and repeat_key_count() == 0. 108 ExpectProcessRecordUserCalledWith(true, KC_A, 0); 109 key_a.press(); 110 run_one_scan_loop(); 111 EXPECT_TRUE(process_record_user_was_called_); 112 113 // After pressing A, the keycode of the key to be repeated is KC_A. 114 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A); 115 EXPECT_EQ(get_last_mods(), 0); 116 117 // Expect the corresponding release event when A is released. 118 ExpectProcessRecordUserCalledWith(false, KC_A, 0); 119 key_a.release(); 120 run_one_scan_loop(); 121 122 for (int n = 1; n <= 2; ++n) { // Tap the Repeat Key twice. 123 // When Repeat is pressed, process_record_user() should be called with a 124 // press event with keycode == KC_A and repeat_key_count() == n. 125 ExpectProcessRecordUserCalledWith(true, KC_A, n); 126 key_repeat.press(); // Press the Repeat Key. 127 run_one_scan_loop(); 128 EXPECT_TRUE(process_record_user_was_called_); 129 130 // Expect the corresponding release event. 131 ExpectProcessRecordUserCalledWith(false, KC_A, n); 132 key_repeat.release(); // Release the Repeat Key. 133 run_one_scan_loop(); 134 EXPECT_TRUE(process_record_user_was_called_); 135 } 136 137 process_record_user_fun = process_record_user_default; 138 tap_key(key_b); 139 // Then after tapping key_b, the keycode to be repeated becomes KC_B. 140 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_B); 141 142 tap_key(key_repeat); 143 144 testing::Mock::VerifyAndClearExpectations(&driver); 145} 146 147// Tests repeating a macro. The keycode FOO_MACRO sends "foo" when pressed. The 148// test taps "FOO_MACRO, Repeat, Repeat", producing "foofoofoo". 149TEST_F(RepeatKey, Macro) { 150 TestDriver driver; 151 KeymapKey key_foo(0, 0, 0, FOO_MACRO); 152 KeymapKey key_repeat(0, 1, 0, QK_REP); 153 set_keymap({key_foo, key_repeat}); 154 155 // Define process_record_user() to handle FOO_MACRO. 156 process_record_user_fun = [](uint16_t keycode, keyrecord_t* record) { 157 switch (keycode) { 158 case FOO_MACRO: 159 if (record->event.pressed) { 160 SEND_STRING("foo"); 161 } 162 break; 163 } 164 return true; 165 }; 166 167 // Allow any number of empty reports. 168 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 169 ExpectString(driver, "foofoofoo"); 170 171 tap_key(key_foo); 172 173 EXPECT_KEYCODE_EQ(get_last_keycode(), FOO_MACRO); 174 175 tap_keys(key_repeat, key_repeat); 176 177 testing::Mock::VerifyAndClearExpectations(&driver); 178} 179 180// Tests a macro with customized repeat behavior: "foo" is sent normally, "bar" 181// on the first repeat, and "baz" on subsequent repeats. The test taps 182// "FOO_MACRO, Repeat, Repeat, FOO_MACRO, Repeat", producing "foobarbazfoobar". 183TEST_F(RepeatKey, MacroCustomRepeat) { 184 TestDriver driver; 185 KeymapKey key_foo(0, 0, 0, FOO_MACRO); 186 KeymapKey key_repeat(0, 1, 0, QK_REP); 187 set_keymap({key_foo, key_repeat}); 188 189 process_record_user_fun = [](uint16_t keycode, keyrecord_t* record) { 190 switch (keycode) { 191 case FOO_MACRO: 192 if (record->event.pressed) { 193 switch (get_repeat_key_count()) { 194 case 0: // When pressed normally. 195 SEND_STRING("foo"); 196 break; 197 case 1: // On first repeat. 198 SEND_STRING("bar"); 199 break; 200 default: // On subsequent repeats. 201 SEND_STRING("baz"); 202 break; 203 } 204 } 205 break; 206 } 207 return true; 208 }; 209 210 // Allow any number of empty reports. 211 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 212 ExpectString(driver, "foobarbazfoobar"); 213 214 tap_key(key_foo); 215 216 EXPECT_KEYCODE_EQ(get_last_keycode(), FOO_MACRO); 217 218 tap_keys(key_repeat, key_repeat, key_foo, key_repeat); 219 220 testing::Mock::VerifyAndClearExpectations(&driver); 221} 222 223// Tests repeating keys on different layers. A 2-layer keymap is defined: 224// Layer 0: QK_REP , MO(1) , KC_A 225// Layer 1: KC_TRNS, KC_TRNS, KC_B 226// The test does the following, which should produce "bbbaaa": 227// 1. Hold MO(1), switching to layer 1. 228// 2. Tap KC_B on layer 1. 229// 3. Release MO(1), switching back to layer 0. 230// 4. Tap Repeat twice. 231// 5. Tap KC_A on layer 0. 232// 6. Hold MO(1), switching to layer 1. 233// 7. Tap Repeat twice. 234TEST_F(RepeatKey, AcrossLayers) { 235 TestDriver driver; 236 KeymapKey key_repeat(0, 0, 0, QK_REP); 237 KeymapKey key_mo_1(0, 1, 0, MO(1)); 238 KeymapKey regular_key(0, 2, 0, KC_A); 239 set_keymap({// Layer 0. 240 key_repeat, key_mo_1, regular_key, 241 // Layer 1. 242 KeymapKey{1, 0, 0, KC_TRNS}, KeymapKey{1, 1, 0, KC_TRNS}, KeymapKey{1, 2, 0, KC_B}}); 243 244 // Allow any number of empty reports. 245 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 246 ExpectString(driver, "bbbaaa"); 247 248 key_mo_1.press(); // Hold the MO(1) layer key. 249 run_one_scan_loop(); 250 tap_key(regular_key); // Taps the KC_B key on layer 1. 251 252 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_B); 253 254 key_mo_1.release(); // Release the layer key. 255 run_one_scan_loop(); 256 tap_keys(key_repeat, key_repeat); 257 tap_key(regular_key); // Taps the KC_A key on layer 0. 258 259 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A); 260 261 key_mo_1.press(); // Hold the layer key. 262 run_one_scan_loop(); 263 tap_keys(key_repeat, key_repeat); 264 265 testing::Mock::VerifyAndClearExpectations(&driver); 266} 267 268// Tests "A(down), Repeat(down), A(up), Repeat(up), Repeat" produces "aaa". 269TEST_F(RepeatKey, RollingToRepeat) { 270 TestDriver driver; 271 KeymapKey key_a(0, 0, 0, KC_A); 272 KeymapKey key_repeat(0, 1, 0, QK_REP); 273 set_keymap({key_a, key_repeat}); 274 275 { 276 InSequence seq; 277 EXPECT_REPORT(driver, (KC_A)); 278 EXPECT_EMPTY_REPORT(driver); 279 EXPECT_REPORT(driver, (KC_A)); 280 EXPECT_EMPTY_REPORT(driver); 281 EXPECT_REPORT(driver, (KC_A)); 282 EXPECT_EMPTY_REPORT(driver); 283 } 284 285 // Perform a rolled press from A to Repeat. 286 287 ExpectProcessRecordUserCalledWith(true, KC_A, 0); 288 key_a.press(); 289 run_one_scan_loop(); 290 EXPECT_TRUE(process_record_user_was_called_); 291 292 ExpectProcessRecordUserCalledWith(true, KC_A, 1); 293 key_repeat.press(); // Press the Repeat Key. 294 run_one_scan_loop(); 295 EXPECT_TRUE(process_record_user_was_called_); 296 297 ExpectProcessRecordUserCalledWith(false, KC_A, 0); 298 key_a.release(); 299 run_one_scan_loop(); 300 EXPECT_TRUE(process_record_user_was_called_); 301 302 ExpectProcessRecordUserCalledWith(false, KC_A, 1); 303 key_repeat.release(); // Release the Repeat Key. 304 run_one_scan_loop(); 305 EXPECT_TRUE(process_record_user_was_called_); 306 307 process_record_user_fun = process_record_user_default; 308 tap_key(key_repeat); 309 310 testing::Mock::VerifyAndClearExpectations(&driver); 311} 312 313// Tests "A, Repeat(down), B(down), Repeat(up), B(up), Repeat" produces "aabb". 314TEST_F(RepeatKey, RollingFromRepeat) { 315 TestDriver driver; 316 KeymapKey key_a(0, 0, 0, KC_A); 317 KeymapKey key_b(0, 1, 0, KC_B); 318 KeymapKey key_repeat(0, 2, 0, QK_REP); 319 set_keymap({key_a, key_b, key_repeat}); 320 321 { 322 InSequence seq; 323 EXPECT_REPORT(driver, (KC_A)); 324 EXPECT_EMPTY_REPORT(driver); 325 EXPECT_REPORT(driver, (KC_A)); 326 EXPECT_REPORT(driver, (KC_A, KC_B)); 327 EXPECT_REPORT(driver, (KC_B)); 328 EXPECT_EMPTY_REPORT(driver); 329 EXPECT_REPORT(driver, (KC_B)); 330 EXPECT_EMPTY_REPORT(driver); 331 } 332 333 tap_key(key_a); 334 335 // Perform a rolled press from Repeat to B. 336 337 ExpectProcessRecordUserCalledWith(true, KC_A, 1); 338 key_repeat.press(); // Press the Repeat Key. 339 run_one_scan_loop(); 340 EXPECT_TRUE(process_record_user_was_called_); 341 342 ExpectProcessRecordUserCalledWith(true, KC_B, 0); 343 key_b.press(); 344 run_one_scan_loop(); 345 EXPECT_TRUE(process_record_user_was_called_); 346 347 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_B); 348 349 ExpectProcessRecordUserCalledWith(false, KC_A, 1); 350 key_repeat.release(); // Release the Repeat Key. 351 run_one_scan_loop(); 352 EXPECT_TRUE(process_record_user_was_called_); 353 354 ExpectProcessRecordUserCalledWith(false, KC_B, 0); 355 key_b.release(); 356 run_one_scan_loop(); 357 EXPECT_TRUE(process_record_user_was_called_); 358 359 process_record_user_fun = process_record_user_default; 360 tap_key(key_repeat); 361 362 testing::Mock::VerifyAndClearExpectations(&driver); 363} 364 365// Tests Repeat Key with a modifier, types "AltGr+C, Repeat, Repeat, C". 366TEST_F(RepeatKey, RecallMods) { 367 TestDriver driver; 368 KeymapKey key_c(0, 0, 0, KC_C); 369 KeymapKey key_altgr(0, 1, 0, KC_RALT); 370 KeymapKey key_repeat(0, 2, 0, QK_REP); 371 set_keymap({key_c, key_altgr, key_repeat}); 372 373 // Allow any number of reports with no keys or only KC_RALT. 374 // clang-format off 375 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 376 KeyboardReport(), 377 KeyboardReport(KC_RALT)))) 378 .Times(AnyNumber()); 379 // clang-format on 380 381 { // Expect: "AltGr+C, AltGr+C, AltGr+C, C". 382 InSequence seq; 383 EXPECT_REPORT(driver, (KC_RALT, KC_C)); 384 EXPECT_REPORT(driver, (KC_RALT, KC_C)); 385 EXPECT_REPORT(driver, (KC_RALT, KC_C)); 386 EXPECT_REPORT(driver, (KC_C)); 387 } 388 389 key_altgr.press(); 390 run_one_scan_loop(); 391 tap_key(key_c); 392 key_altgr.release(); 393 run_one_scan_loop(); 394 395 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_C); 396 EXPECT_EQ(get_last_mods(), MOD_BIT(KC_RALT)); 397 398 tap_keys(key_repeat, key_repeat, key_c); 399 400 testing::Mock::VerifyAndClearExpectations(&driver); 401} 402 403// Tests that Repeat Key stacks mods, types 404// "Ctrl+Left, Repeat, Shift+Repeat, Shift+Repeat, Repeat, Left". 405TEST_F(RepeatKey, StackMods) { 406 TestDriver driver; 407 KeymapKey key_left(0, 0, 0, KC_LEFT); 408 KeymapKey key_shift(0, 1, 0, KC_LSFT); 409 KeymapKey key_ctrl(0, 2, 0, KC_LCTL); 410 KeymapKey key_repeat(0, 3, 0, QK_REP); 411 set_keymap({key_left, key_shift, key_ctrl, key_repeat}); 412 413 // Allow any number of reports with no keys or only mods. 414 // clang-format off 415 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 416 KeyboardReport(), 417 KeyboardReport(KC_LCTL), 418 KeyboardReport(KC_LSFT), 419 KeyboardReport(KC_LCTL, KC_LSFT)))) 420 .Times(AnyNumber()); 421 // clang-format on 422 423 { // Expect: "Ctrl+Left, Ctrl+Shift+Left". 424 InSequence seq; 425 EXPECT_REPORT(driver, (KC_LCTL, KC_LEFT)); 426 EXPECT_REPORT(driver, (KC_LCTL, KC_LEFT)); 427 EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_LEFT)); 428 EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_LEFT)); 429 EXPECT_REPORT(driver, (KC_LCTL, KC_LEFT)); 430 EXPECT_REPORT(driver, (KC_LEFT)); 431 } 432 433 key_ctrl.press(); 434 run_one_scan_loop(); 435 tap_key(key_left); 436 run_one_scan_loop(); 437 key_ctrl.release(); 438 run_one_scan_loop(); 439 440 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_LEFT); 441 EXPECT_EQ(get_last_mods(), MOD_BIT(KC_LCTL)); 442 443 tap_key(key_repeat); 444 445 key_shift.press(); 446 run_one_scan_loop(); 447 tap_keys(key_repeat, key_repeat); 448 key_shift.release(); 449 run_one_scan_loop(); 450 451 EXPECT_EQ(get_last_mods(), MOD_BIT(KC_LCTL)); 452 453 tap_keys(key_repeat, key_left); 454 455 testing::Mock::VerifyAndClearExpectations(&driver); 456} 457 458// Types: "S(KC_1), Repeat, Ctrl+Repeat, Ctrl+Repeat, Repeat, KC_2". 459TEST_F(RepeatKey, ShiftedKeycode) { 460 TestDriver driver; 461 KeymapKey key_exlm(0, 0, 0, S(KC_1)); 462 KeymapKey key_2(0, 1, 0, KC_2); 463 KeymapKey key_ctrl(0, 2, 0, KC_LCTL); 464 KeymapKey key_repeat(0, 3, 0, QK_REP); 465 set_keymap({key_exlm, key_2, key_ctrl, key_repeat}); 466 467 // Allow any number of reports with no keys or only mods. 468 // clang-format off 469 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 470 KeyboardReport(), 471 KeyboardReport(KC_LCTL), 472 KeyboardReport(KC_LSFT), 473 KeyboardReport(KC_LCTL, KC_LSFT)))) 474 .Times(AnyNumber()); 475 // clang-format on 476 477 { // Expect: "Shift+1, Shift+1, Ctrl+Shift+1, Ctrl+Shift+1, Shift+1, 2". 478 InSequence seq; 479 EXPECT_REPORT(driver, (KC_LSFT, KC_1)); 480 EXPECT_REPORT(driver, (KC_LSFT, KC_1)); 481 EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_1)); 482 EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_1)); 483 EXPECT_REPORT(driver, (KC_LSFT, KC_1)); 484 EXPECT_REPORT(driver, (KC_2)); 485 } 486 487 tap_key(key_exlm); 488 489 EXPECT_KEYCODE_EQ(get_last_keycode(), S(KC_1)); 490 491 tap_key(key_repeat); 492 493 key_ctrl.press(); 494 run_one_scan_loop(); 495 tap_keys(key_repeat, key_repeat); 496 key_ctrl.release(); 497 run_one_scan_loop(); 498 499 tap_keys(key_repeat, key_2); 500 501 testing::Mock::VerifyAndClearExpectations(&driver); 502} 503 504// Tests Repeat Key with a one-shot Shift, types 505// "A, OSM(MOD_LSFT), Repeat, Repeat". 506TEST_F(RepeatKey, WithOneShotShift) { 507 TestDriver driver; 508 KeymapKey key_a(0, 0, 0, KC_A); 509 KeymapKey key_oneshot_shift(0, 1, 0, OSM(MOD_LSFT)); 510 KeymapKey key_repeat(0, 2, 0, QK_REP); 511 set_keymap({key_a, key_oneshot_shift, key_repeat}); 512 513 // Allow any number of reports with no keys or only KC_RALT. 514 // clang-format off 515 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 516 KeyboardReport(), 517 KeyboardReport(KC_LSFT)))) 518 .Times(AnyNumber()); 519 // clang-format on 520 ExpectString(driver, "aAa"); 521 522 tap_keys(key_a, key_oneshot_shift, key_repeat, key_repeat); 523 524 testing::Mock::VerifyAndClearExpectations(&driver); 525} 526 527// Tests Repeat Key with a mod-tap key, types 528// "A, Repeat, Repeat, A(down), Repeat, Repeat, A(up), Repeat". 529TEST_F(RepeatKey, ModTap) { 530 TestDriver driver; 531 KeymapKey key_mt_a(0, 0, 0, LSFT_T(KC_A)); 532 KeymapKey key_repeat(0, 1, 0, QK_REP); 533 set_keymap({key_mt_a, key_repeat}); 534 535 // Allow any number of reports with no keys or only KC_LSFT. 536 // clang-format off 537 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 538 KeyboardReport(), 539 KeyboardReport(KC_LSFT)))) 540 .Times(AnyNumber()); 541 // clang-format on 542 ExpectString(driver, "aaaAAa"); 543 544 tap_key(key_mt_a); 545 546 EXPECT_KEYCODE_EQ(get_last_keycode(), LSFT_T(KC_A)); 547 548 tap_keys(key_repeat, key_repeat); 549 key_mt_a.press(); 550 run_one_scan_loop(); 551 tap_key(key_repeat, TAPPING_TERM + 1); 552 tap_key(key_repeat); 553 key_mt_a.release(); 554 run_one_scan_loop(); 555 tap_key(key_repeat); 556 557 testing::Mock::VerifyAndClearExpectations(&driver); 558} 559 560// Tests with Auto Shift. When repeating an autoshiftable key, it does not 561// matter how long the original key was held, rather, quickly tapping vs. 562// long-pressing the Repeat Key determines whether the shifted key is repeated. 563// 564// The test does the following, which should produce "aaABbB": 565// 1. Tap KC_A quickly. 566// 2. Tap Repeat Key quickly. 567// 3. Long-press Repeat Key. 568// 4. Long-press KC_B. 569// 5. Tap Repeat Key quickly. 570// 6. Long-press Repeat Key. 571TEST_F(RepeatKey, AutoShift) { 572 TestDriver driver; 573 KeymapKey key_a(0, 0, 0, KC_A); 574 KeymapKey key_b(0, 1, 0, KC_B); 575 KeymapKey key_repeat(0, 2, 0, QK_REP); 576 set_keymap({key_a, key_b, key_repeat}); 577 578 autoshift_enable(); 579 580 // Allow any number of reports with no keys or only KC_LSFT. 581 // clang-format off 582 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 583 KeyboardReport(), 584 KeyboardReport(KC_LSFT)))) 585 .Times(AnyNumber()); 586 // clang-format on 587 ExpectString(driver, "aaABbB"); 588 589 tap_key(key_a); // Tap A quickly. 590 591 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A); 592 EXPECT_EQ(get_last_mods(), 0); 593 594 tap_key(key_repeat); 595 tap_key(key_repeat, AUTO_SHIFT_TIMEOUT + 1); 596 597 tap_key(key_b, AUTO_SHIFT_TIMEOUT + 1); // Long press B. 598 599 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_B); 600 EXPECT_EQ(get_last_mods(), 0); 601 602 tap_key(key_repeat); 603 tap_key(key_repeat, AUTO_SHIFT_TIMEOUT + 1); 604 605 testing::Mock::VerifyAndClearExpectations(&driver); 606} 607 608// Defines `remember_last_key_user()` to forget the Shift mod and types: 609// "Ctrl+A, Repeat, Shift+A, Repeat, Shift+Repeat". 610TEST_F(RepeatKey, FilterRememberedMods) { 611 TestDriver driver; 612 KeymapKey key_a(0, 0, 0, KC_A); 613 KeymapKey key_ctrl(0, 1, 0, KC_LCTL); 614 KeymapKey key_shift(0, 2, 0, KC_LSFT); 615 KeymapKey key_repeat(0, 3, 0, QK_REP); 616 set_keymap({key_a, key_ctrl, key_shift, key_repeat}); 617 618 remember_last_key_user_fun = [](uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) { 619 *remembered_mods &= ~MOD_MASK_SHIFT; 620 return true; 621 }; 622 623 // Allow any number of reports with no keys or only mods. 624 // clang-format off 625 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 626 KeyboardReport(), 627 KeyboardReport(KC_LCTL), 628 KeyboardReport(KC_LSFT), 629 KeyboardReport(KC_LCTL, KC_LSFT)))) 630 .Times(AnyNumber()); 631 // clang-format on 632 633 { // Expect: "Ctrl+A, Ctrl+A, Shift+A, A, Shift+A". 634 InSequence seq; 635 EXPECT_REPORT(driver, (KC_LCTL, KC_A)); 636 EXPECT_REPORT(driver, (KC_LCTL, KC_A)); 637 EXPECT_REPORT(driver, (KC_LSFT, KC_A)); 638 EXPECT_REPORT(driver, (KC_A)); 639 EXPECT_REPORT(driver, (KC_LSFT, KC_A)); 640 } 641 642 key_ctrl.press(); 643 run_one_scan_loop(); 644 tap_key(key_a); 645 646 EXPECT_EQ(get_last_mods(), MOD_BIT(KC_LCTL)); 647 648 key_ctrl.release(); 649 run_one_scan_loop(); 650 651 tap_key(key_repeat); 652 key_shift.press(); 653 run_one_scan_loop(); 654 tap_key(key_a); 655 656 EXPECT_EQ(get_last_mods(), 0); // Shift should be forgotten. 657 658 key_shift.release(); 659 run_one_scan_loop(); 660 661 tap_key(key_repeat); 662 663 key_shift.press(); 664 run_one_scan_loop(); 665 tap_key(key_repeat); 666 key_shift.release(); 667 run_one_scan_loop(); 668 669 testing::Mock::VerifyAndClearExpectations(&driver); 670} 671 672// Tests set_last_keycode() and set_last_mods(). 673TEST_F(RepeatKey, SetRepeatKeyKeycode) { 674 TestDriver driver; 675 KeymapKey key_repeat(0, 0, 0, QK_REP); 676 set_keymap({key_repeat}); 677 678 // Allow any number of reports with no keys or only KC_LSFT. 679 // clang-format off 680 EXPECT_CALL(driver, send_keyboard_mock(AnyOf( 681 KeyboardReport(), 682 KeyboardReport(KC_LSFT)))) 683 .Times(AnyNumber()); 684 // clang-format on 685 ExpectString(driver, "aaBB"); 686 687 set_last_keycode(KC_A); 688 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A); 689 690 for (int n = 1; n <= 2; ++n) { // Tap the Repeat Key twice. 691 // When Repeat is pressed, process_record_user() should be called with a 692 // press event with keycode == KC_A and repeat_key_count() == n. 693 ExpectProcessRecordUserCalledWith(true, KC_A, n); 694 key_repeat.press(); // Press the Repeat Key. 695 run_one_scan_loop(); 696 EXPECT_TRUE(process_record_user_was_called_); 697 698 // Expect the corresponding release event. 699 ExpectProcessRecordUserCalledWith(false, KC_A, n); 700 key_repeat.release(); // Release the Repeat Key. 701 run_one_scan_loop(); 702 EXPECT_TRUE(process_record_user_was_called_); 703 } 704 705 process_record_user_fun = process_record_user_default; 706 set_last_keycode(KC_B); 707 set_last_mods(MOD_BIT(KC_LSFT)); 708 709 tap_keys(key_repeat, key_repeat); 710 711 set_last_keycode(KC_NO); 712 tap_keys(key_repeat, key_repeat); // Has no effect. 713 714 testing::Mock::VerifyAndClearExpectations(&driver); 715} 716 717// Tests the `repeat_key_invoke()` function. 718TEST_F(RepeatKey, RepeatKeyInvoke) { 719 TestDriver driver; 720 KeymapKey key_s(0, 0, 0, KC_S); 721 set_keymap({key_s}); 722 723 // Allow any number of empty reports. 724 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 725 ExpectString(driver, "ss"); 726 727 tap_key(key_s); 728 729 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_S); 730 731 // Calling repeat_key_invoke() should result in process_record_user() 732 // getting a press event with keycode KC_S. 733 ExpectProcessRecordUserCalledWith(true, KC_S, 1); 734 keyevent_t event; 735 event.key = {0, 0}; 736 event.pressed = true; 737 event.time = timer_read(); 738 event.type = KEY_EVENT; 739 repeat_key_invoke(&event); 740 run_one_scan_loop(); 741 EXPECT_TRUE(process_record_user_was_called_); 742 743 // Make the release event. 744 ExpectProcessRecordUserCalledWith(false, KC_S, 1); 745 event.pressed = false; 746 event.time = timer_read(); 747 repeat_key_invoke(&event); 748 run_one_scan_loop(); 749 EXPECT_TRUE(process_record_user_was_called_); 750 751 testing::Mock::VerifyAndClearExpectations(&driver); 752} 753 754// Check that mods and Layer Lock are not remembered. 755TEST_F(RepeatKey, IgnoredKeys) { 756 TestDriver driver; 757 KeymapKey regular_key(0, 0, 0, KC_A); 758 KeymapKey key_repeat(0, 1, 0, QK_REP); 759 KeymapKey key_lsft(0, 2, 0, KC_LSFT); 760 KeymapKey key_lctl(0, 3, 0, KC_LCTL); 761 KeymapKey key_llck(0, 4, 0, QK_LAYER_LOCK); 762 set_keymap({regular_key, key_repeat, key_lsft, key_lctl, key_llck}); 763 764 // Allow any number of empty reports. 765 EXPECT_EMPTY_REPORT(driver).Times(AnyNumber()); 766 { 767 InSequence seq; 768 EXPECT_REPORT(driver, (KC_A)); 769 EXPECT_REPORT(driver, (KC_LSFT)); 770 EXPECT_REPORT(driver, (KC_LCTL)); 771 EXPECT_REPORT(driver, (KC_A)); 772 EXPECT_REPORT(driver, (KC_A)); 773 } 774 775 tap_key(regular_key); // Taps the KC_A key. 776 777 // Tap Shift, Ctrl, and Layer Lock keys, which should not be remembered. 778 tap_keys(key_lsft, key_lctl, key_llck); 779 EXPECT_KEYCODE_EQ(get_last_keycode(), KC_A); 780 781 // Tapping the Repeat Key should still reproduce KC_A. 782 tap_keys(key_repeat, key_repeat); 783 784 testing::Mock::VerifyAndClearExpectations(&driver); 785} 786 787} // namespace