test_caps_word.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. // Copyright 2022 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. #include "keyboard_report_util.hpp"
  16. #include "keycode.h"
  17. #include "test_common.hpp"
  18. #include "test_fixture.hpp"
  19. #include "test_keymap_key.hpp"
  20. using ::testing::_;
  21. using ::testing::AnyNumber;
  22. using ::testing::AnyOf;
  23. using ::testing::InSequence;
  24. using ::testing::TestParamInfo;
  25. namespace {
  26. bool press_user_default(uint16_t keycode) {
  27. switch (keycode) {
  28. // Keycodes that continue Caps Word, with shift applied.
  29. case KC_A ... KC_Z:
  30. case KC_MINS:
  31. add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key.
  32. return true;
  33. // Keycodes that continue Caps Word, without shifting.
  34. case KC_1 ... KC_0:
  35. case KC_BSPC:
  36. case KC_DEL:
  37. case KC_UNDS:
  38. return true;
  39. default:
  40. return false; // Deactivate Caps Word.
  41. }
  42. }
  43. uint16_t passed_keycode;
  44. bool press_user_save_passed_keycode(uint16_t keycode) {
  45. passed_keycode = keycode;
  46. return true;
  47. }
  48. bool (*press_user_fun)(uint16_t) = press_user_default;
  49. extern "C" {
  50. bool caps_word_press_user(uint16_t keycode) {
  51. return press_user_fun(keycode);
  52. }
  53. } // extern "C"
  54. class CapsWord : public TestFixture {
  55. public:
  56. void SetUp() override {
  57. caps_word_off();
  58. press_user_fun = press_user_default;
  59. }
  60. };
  61. // Tests caps_word_on(), _off(), and _toggle() functions.
  62. TEST_F(CapsWord, OnOffToggleFuns) {
  63. TestDriver driver;
  64. EXPECT_EQ(is_caps_word_on(), false);
  65. caps_word_on();
  66. EXPECT_EQ(is_caps_word_on(), true);
  67. caps_word_on();
  68. EXPECT_EQ(is_caps_word_on(), true);
  69. caps_word_off();
  70. EXPECT_EQ(is_caps_word_on(), false);
  71. caps_word_off();
  72. EXPECT_EQ(is_caps_word_on(), false);
  73. caps_word_toggle();
  74. EXPECT_EQ(is_caps_word_on(), true);
  75. caps_word_toggle();
  76. EXPECT_EQ(is_caps_word_on(), false);
  77. testing::Mock::VerifyAndClearExpectations(&driver);
  78. }
  79. // Tests the default `caps_word_press_user()` function.
  80. TEST_F(CapsWord, DefaultCapsWordPressUserFun) {
  81. // Spot check some keycodes that continue Caps Word, with shift applied.
  82. for (uint16_t keycode : {KC_A, KC_B, KC_Z, KC_MINS}) {
  83. SCOPED_TRACE("keycode: " + testing::PrintToString(keycode));
  84. clear_weak_mods();
  85. EXPECT_TRUE(caps_word_press_user(keycode));
  86. EXPECT_EQ(get_weak_mods(), MOD_BIT(KC_LSFT));
  87. }
  88. // Some keycodes that continue Caps Word, without shifting.
  89. for (uint16_t keycode : {KC_1, KC_9, KC_0, KC_BSPC, KC_DEL}) {
  90. SCOPED_TRACE("keycode: " + testing::PrintToString(keycode));
  91. clear_weak_mods();
  92. EXPECT_TRUE(caps_word_press_user(keycode));
  93. EXPECT_EQ(get_weak_mods(), 0);
  94. }
  95. // Some keycodes that turn off Caps Word.
  96. for (uint16_t keycode : {KC_SPC, KC_DOT, KC_COMM, KC_TAB, KC_ESC, KC_ENT}) {
  97. SCOPED_TRACE("keycode: " + testing::PrintToString(keycode));
  98. EXPECT_FALSE(caps_word_press_user(keycode));
  99. }
  100. }
  101. // Tests that `QK_CAPS_WORD_TOGGLE` key toggles Caps Word.
  102. TEST_F(CapsWord, CapswrdKey) {
  103. TestDriver driver;
  104. KeymapKey key_capswrd(0, 0, 0, QK_CAPS_WORD_TOGGLE);
  105. set_keymap({key_capswrd});
  106. // No keyboard reports should be sent.
  107. EXPECT_NO_REPORT(driver);
  108. tap_key(key_capswrd); // Tap the QK_CAPS_WORD_TOGGLE key.
  109. EXPECT_EQ(is_caps_word_on(), true);
  110. tap_key(key_capswrd); // Tap the QK_CAPS_WORD_TOGGLE key again.
  111. EXPECT_EQ(is_caps_word_on(), false);
  112. testing::Mock::VerifyAndClearExpectations(&driver);
  113. }
  114. // Tests that being idle for CAPS_WORD_IDLE_TIMEOUT turns off Caps Word.
  115. TEST_F(CapsWord, IdleTimeout) {
  116. TestDriver driver;
  117. KeymapKey key_a(0, 0, 0, KC_A);
  118. set_keymap({key_a});
  119. // Allow any number of reports with no keys or only KC_LSFT.
  120. // clang-format off
  121. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  122. KeyboardReport(),
  123. KeyboardReport(KC_LSFT))))
  124. .Times(AnyNumber());
  125. // clang-format on
  126. // Expect "Shift+A".
  127. EXPECT_REPORT(driver, (KC_LSFT, KC_A));
  128. // Turn on Caps Word and tap "A".
  129. caps_word_on();
  130. tap_key(key_a);
  131. testing::Mock::VerifyAndClearExpectations(&driver);
  132. idle_for(CAPS_WORD_IDLE_TIMEOUT);
  133. run_one_scan_loop();
  134. // Caps Word should be off and mods should be clear.
  135. EXPECT_EQ(is_caps_word_on(), false);
  136. EXPECT_EQ(get_mods() | get_weak_mods(), 0);
  137. EXPECT_EMPTY_REPORT(driver).Times(AnyNumber());
  138. // Expect unshifted "A".
  139. EXPECT_REPORT(driver, (KC_A));
  140. tap_key(key_a);
  141. testing::Mock::VerifyAndClearExpectations(&driver);
  142. }
  143. // Tests that typing "A, 4, A, 4" produces "Shift+A, 4, Shift+A, 4".
  144. TEST_F(CapsWord, ShiftsLettersButNotDigits) {
  145. TestDriver driver;
  146. KeymapKey key_a(0, 0, 0, KC_A);
  147. KeymapKey key_4(0, 1, 0, KC_4);
  148. set_keymap({key_a, key_4});
  149. // Allow any number of reports with no keys or only KC_LSFT.
  150. // clang-format off
  151. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  152. KeyboardReport(),
  153. KeyboardReport(KC_LSFT))))
  154. .Times(AnyNumber());
  155. // clang-format on
  156. { // Expect: "Shift+A, 4, Shift+A, 4".
  157. InSequence s;
  158. EXPECT_REPORT(driver, (KC_LSFT, KC_A));
  159. EXPECT_REPORT(driver, (KC_4));
  160. EXPECT_REPORT(driver, (KC_LSFT, KC_A));
  161. EXPECT_REPORT(driver, (KC_4));
  162. }
  163. // Turn on Caps Word and tap "A, 4, A, 4".
  164. caps_word_on();
  165. tap_keys(key_a, key_4, key_a, key_4);
  166. testing::Mock::VerifyAndClearExpectations(&driver);
  167. }
  168. // Tests that typing "A, Space, A" produces "Shift+A, Space, A".
  169. TEST_F(CapsWord, SpaceTurnsOffCapsWord) {
  170. TestDriver driver;
  171. KeymapKey key_a(0, 0, 0, KC_A);
  172. KeymapKey key_spc(0, 1, 0, KC_SPC);
  173. set_keymap({key_a, key_spc});
  174. // Allow any number of reports with no keys or only KC_LSFT.
  175. // clang-format off
  176. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  177. KeyboardReport(),
  178. KeyboardReport(KC_LSFT))))
  179. .Times(AnyNumber());
  180. // clang-format on
  181. { // Expect: "Shift+A, Space, A".
  182. InSequence seq;
  183. EXPECT_REPORT(driver, (KC_LSFT, KC_A));
  184. EXPECT_REPORT(driver, (KC_SPC));
  185. EXPECT_REPORT(driver, (KC_A));
  186. }
  187. // Turn on Caps Word and tap "A, Space, A".
  188. caps_word_on();
  189. tap_keys(key_a, key_spc, key_a);
  190. testing::Mock::VerifyAndClearExpectations(&driver);
  191. }
  192. // Tests that typing "AltGr + A" produces "Shift + AltGr + A".
  193. TEST_F(CapsWord, ShiftsAltGrSymbols) {
  194. TestDriver driver;
  195. KeymapKey key_a(0, 0, 0, KC_A);
  196. KeymapKey key_altgr(0, 1, 0, KC_RALT);
  197. set_keymap({key_a, key_altgr});
  198. // Allow any number of reports with no keys or only modifiers.
  199. // clang-format off
  200. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  201. KeyboardReport(),
  202. KeyboardReport(KC_RALT),
  203. KeyboardReport(KC_LSFT, KC_RALT))))
  204. .Times(AnyNumber());
  205. // Expect "Shift + AltGr + A".
  206. EXPECT_REPORT(driver, (KC_LSFT, KC_RALT, KC_A));
  207. // clang-format on
  208. // Turn on Caps Word and type "AltGr + A".
  209. caps_word_on();
  210. key_altgr.press();
  211. run_one_scan_loop();
  212. tap_key(key_a);
  213. run_one_scan_loop();
  214. key_altgr.release();
  215. testing::Mock::VerifyAndClearExpectations(&driver);
  216. }
  217. // Tests typing "AltGr + A" using a mod-tap key.
  218. TEST_F(CapsWord, ShiftsModTapAltGrSymbols) {
  219. TestDriver driver;
  220. KeymapKey key_a(0, 0, 0, KC_A);
  221. KeymapKey key_altgr_t(0, 1, 0, RALT_T(KC_B));
  222. set_keymap({key_a, key_altgr_t});
  223. // Allow any number of reports with no keys or only modifiers.
  224. // clang-format off
  225. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  226. KeyboardReport(),
  227. KeyboardReport(KC_RALT),
  228. KeyboardReport(KC_LSFT, KC_RALT))))
  229. .Times(AnyNumber());
  230. // Expect "Shift + AltGr + A".
  231. EXPECT_REPORT(driver, (KC_LSFT, KC_RALT, KC_A));
  232. // clang-format on
  233. // Turn on Caps Word and type "AltGr + A".
  234. caps_word_on();
  235. key_altgr_t.press();
  236. idle_for(TAPPING_TERM + 1);
  237. tap_key(key_a);
  238. run_one_scan_loop();
  239. key_altgr_t.release();
  240. EXPECT_TRUE(is_caps_word_on());
  241. testing::Mock::VerifyAndClearExpectations(&driver);
  242. }
  243. struct CapsWordPressUserParams {
  244. std::string name;
  245. uint16_t keycode;
  246. uint16_t delay_ms;
  247. uint16_t expected_passed_keycode;
  248. bool continues_caps_word;
  249. static const std::string& GetName(const TestParamInfo<CapsWordPressUserParams>& info) {
  250. return info.param.name;
  251. }
  252. };
  253. class CapsWordPressUser : public ::testing::WithParamInterface<CapsWordPressUserParams>, public CapsWord {
  254. void SetUp() override {
  255. caps_word_on();
  256. passed_keycode = KC_NO;
  257. press_user_fun = press_user_save_passed_keycode;
  258. }
  259. };
  260. // Tests keycodes passed to caps_word_press_user() function for various keys.
  261. TEST_P(CapsWordPressUser, KeyCode) {
  262. TestDriver driver;
  263. KeymapKey key(0, 0, 0, GetParam().keycode);
  264. set_keymap({key});
  265. EXPECT_ANY_REPORT(driver).Times(AnyNumber());
  266. tap_key(key, GetParam().delay_ms);
  267. EXPECT_EQ(passed_keycode, GetParam().expected_passed_keycode);
  268. EXPECT_EQ(is_caps_word_on(), GetParam().continues_caps_word);
  269. clear_oneshot_mods();
  270. testing::Mock::VerifyAndClearExpectations(&driver);
  271. }
  272. const uint16_t LT_1_KC_A = LT(1, KC_A);
  273. // clang-format off
  274. INSTANTIATE_TEST_CASE_P(
  275. PressUser,
  276. CapsWordPressUser,
  277. ::testing::Values(
  278. CapsWordPressUserParams{
  279. "KC_A", KC_A, 1, KC_A, true},
  280. CapsWordPressUserParams{
  281. "KC_HASH", KC_HASH, 1, KC_HASH, true},
  282. CapsWordPressUserParams{
  283. "KC_LSFT", KC_LSFT, 1, KC_LSFT, true},
  284. CapsWordPressUserParams{
  285. "KC_RSFT", KC_RSFT, 1, KC_RSFT, true},
  286. CapsWordPressUserParams{
  287. "LSFT_T_tapped", LSFT_T(KC_A), 1, KC_A, true},
  288. CapsWordPressUserParams{
  289. "LSFT_T_held", LSFT_T(KC_A), TAPPING_TERM + 1, KC_LSFT, true},
  290. CapsWordPressUserParams{
  291. "RSFT_T_held", RSFT_T(KC_A), TAPPING_TERM + 1, KC_RSFT, true},
  292. CapsWordPressUserParams{
  293. "RSA_T_held", RSA_T(KC_A), TAPPING_TERM + 1, RSFT(KC_RALT), true},
  294. // Holding a mod-tap other than Shift or AltGr stops Caps Word.
  295. CapsWordPressUserParams{
  296. "LCTL_T_held", LCTL_T(KC_A), TAPPING_TERM + 1, KC_NO, false},
  297. CapsWordPressUserParams{
  298. "LALT_T_held", LALT_T(KC_A), TAPPING_TERM + 1, KC_NO, false},
  299. CapsWordPressUserParams{
  300. "LGUI_T_held", LGUI_T(KC_A), TAPPING_TERM + 1, KC_NO, false},
  301. // Layer keys are ignored and continue Caps Word.
  302. CapsWordPressUserParams{
  303. "MO", MO(1), 1, KC_NO, true},
  304. CapsWordPressUserParams{
  305. "TO", TO(1), 1, KC_NO, true},
  306. CapsWordPressUserParams{
  307. "TG", TG(1), 1, KC_NO, true},
  308. CapsWordPressUserParams{
  309. "TT", TT(1), 1, KC_NO, true},
  310. CapsWordPressUserParams{
  311. "OSL", OSL(1), 1, KC_NO, true},
  312. CapsWordPressUserParams{
  313. "LT_held", LT_1_KC_A, TAPPING_TERM + 1, KC_NO, true},
  314. // AltGr keys are ignored and continue Caps Word.
  315. CapsWordPressUserParams{
  316. "KC_RALT", KC_RALT, 1, KC_NO, true},
  317. CapsWordPressUserParams{
  318. "OSM_MOD_RALT", OSM(MOD_RALT), 1, KC_NO, true},
  319. CapsWordPressUserParams{
  320. "RALT_T_held", RALT_T(KC_A), TAPPING_TERM + 1, KC_NO, true}
  321. ),
  322. CapsWordPressUserParams::GetName
  323. );
  324. // clang-format on
  325. struct CapsWordBothShiftsParams {
  326. std::string name;
  327. uint16_t left_shift_keycode;
  328. uint16_t right_shift_keycode;
  329. static const std::string& GetName(const TestParamInfo<CapsWordBothShiftsParams>& info) {
  330. return info.param.name;
  331. }
  332. };
  333. // Tests the BOTH_SHIFTS_TURNS_ON_CAPS_WORD method to turn on Caps Word.
  334. class CapsWordBothShifts : public ::testing::WithParamInterface<CapsWordBothShiftsParams>, public CapsWord {};
  335. // Pressing shifts as "Left down, Right down, Left up, Right up".
  336. TEST_P(CapsWordBothShifts, PressLRLR) {
  337. TestDriver driver;
  338. KeymapKey left_shift(0, 0, 0, GetParam().left_shift_keycode);
  339. KeymapKey right_shift(0, 1, 0, GetParam().right_shift_keycode);
  340. set_keymap({left_shift, right_shift});
  341. // clang-format off
  342. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  343. KeyboardReport(),
  344. KeyboardReport(KC_LSFT),
  345. KeyboardReport(KC_RSFT),
  346. KeyboardReport(KC_LSFT, KC_RSFT))))
  347. .Times(AnyNumber());
  348. // clang-format on
  349. EXPECT_EQ(is_caps_word_on(), false);
  350. left_shift.press(); // Press both shifts.
  351. run_one_scan_loop();
  352. right_shift.press();
  353. // For mod-tap and Space Cadet keys, wait for the tapping term.
  354. if (left_shift.code == LSFT_T(KC_A) || left_shift.code == QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN) {
  355. idle_for(TAPPING_TERM);
  356. }
  357. run_one_scan_loop();
  358. left_shift.release(); // Release both.
  359. run_one_scan_loop();
  360. right_shift.release();
  361. run_one_scan_loop();
  362. EXPECT_EQ(is_caps_word_on(), true);
  363. testing::Mock::VerifyAndClearExpectations(&driver);
  364. }
  365. // Pressing shifts as "Left down, Right down, Right up, Left up".
  366. TEST_P(CapsWordBothShifts, PressLRRL) {
  367. TestDriver driver;
  368. KeymapKey left_shift(0, 0, 0, GetParam().left_shift_keycode);
  369. KeymapKey right_shift(0, 1, 0, GetParam().right_shift_keycode);
  370. set_keymap({left_shift, right_shift});
  371. // clang-format off
  372. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  373. KeyboardReport(),
  374. KeyboardReport(KC_LSFT),
  375. KeyboardReport(KC_RSFT),
  376. KeyboardReport(KC_LSFT, KC_RSFT))))
  377. .Times(AnyNumber());
  378. // clang-format on
  379. EXPECT_EQ(is_caps_word_on(), false);
  380. left_shift.press(); // Press both shifts.
  381. run_one_scan_loop();
  382. right_shift.press();
  383. if (left_shift.code == LSFT_T(KC_A) || left_shift.code == QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN) {
  384. idle_for(TAPPING_TERM);
  385. }
  386. run_one_scan_loop();
  387. right_shift.release(); // Release both.
  388. run_one_scan_loop();
  389. left_shift.release();
  390. run_one_scan_loop();
  391. EXPECT_EQ(is_caps_word_on(), true);
  392. testing::Mock::VerifyAndClearExpectations(&driver);
  393. }
  394. // clang-format off
  395. INSTANTIATE_TEST_CASE_P(
  396. ShiftPairs,
  397. CapsWordBothShifts,
  398. ::testing::Values(
  399. CapsWordBothShiftsParams{
  400. "PlainShifts", KC_LSFT, KC_RSFT},
  401. CapsWordBothShiftsParams{
  402. "OneshotShifts", OSM(MOD_LSFT), OSM(MOD_RSFT)},
  403. CapsWordBothShiftsParams{
  404. "SpaceCadetShifts", SC_LSPO, SC_RSPC},
  405. CapsWordBothShiftsParams{
  406. "ModTapShifts", LSFT_T(KC_A), RSFT_T(KC_B)}
  407. ),
  408. CapsWordBothShiftsParams::GetName
  409. );
  410. // clang-format on
  411. struct CapsWordDoubleTapShiftParams {
  412. std::string name;
  413. uint16_t left_shift_keycode;
  414. static const std::string& GetName(const TestParamInfo<CapsWordDoubleTapShiftParams>& info) {
  415. return info.param.name;
  416. }
  417. };
  418. // Tests the DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD method to turn on Caps Word.
  419. class CapsWordDoubleTapShift : public ::testing::WithParamInterface<CapsWordDoubleTapShiftParams>, public CapsWord {};
  420. // Tests that double tapping activates Caps Word.
  421. TEST_P(CapsWordDoubleTapShift, Activation) {
  422. TestDriver driver;
  423. KeymapKey left_shift(0, 0, 0, GetParam().left_shift_keycode);
  424. set_keymap({left_shift});
  425. // clang-format off
  426. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  427. KeyboardReport(),
  428. KeyboardReport(KC_LSFT))))
  429. .Times(AnyNumber());
  430. // clang-format on
  431. EXPECT_EQ(is_caps_word_on(), false);
  432. // Tapping shift twice within the tapping term turns on Caps Word.
  433. tap_key(left_shift);
  434. idle_for(TAPPING_TERM - 10);
  435. tap_key(left_shift);
  436. EXPECT_EQ(is_caps_word_on(), true);
  437. testing::Mock::VerifyAndClearExpectations(&driver);
  438. }
  439. // Double tap doesn't count if another key is pressed between the taps.
  440. TEST_P(CapsWordDoubleTapShift, Interrupted) {
  441. TestDriver driver;
  442. KeymapKey left_shift(0, 0, 0, GetParam().left_shift_keycode);
  443. KeymapKey key_a(0, 1, 0, KC_A);
  444. set_keymap({left_shift, key_a});
  445. // clang-format off
  446. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  447. KeyboardReport(),
  448. KeyboardReport(KC_LSFT),
  449. KeyboardReport(KC_LSFT, KC_A))))
  450. .Times(AnyNumber());
  451. // clang-format on
  452. left_shift.press();
  453. run_one_scan_loop();
  454. tap_key(key_a); // 'A' key interrupts the double tap.
  455. left_shift.release();
  456. run_one_scan_loop();
  457. idle_for(TAPPING_TERM - 10);
  458. tap_key(left_shift);
  459. EXPECT_EQ(is_caps_word_on(), false); // Caps Word is still off.
  460. clear_oneshot_mods();
  461. testing::Mock::VerifyAndClearExpectations(&driver);
  462. }
  463. // Double tap doesn't count if taps are more than tapping term apart.
  464. TEST_P(CapsWordDoubleTapShift, SlowTaps) {
  465. TestDriver driver;
  466. KeymapKey left_shift(0, 0, 0, GetParam().left_shift_keycode);
  467. set_keymap({left_shift});
  468. // clang-format off
  469. EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
  470. KeyboardReport(),
  471. KeyboardReport(KC_LSFT))))
  472. .Times(AnyNumber());
  473. // clang-format on
  474. tap_key(left_shift);
  475. idle_for(TAPPING_TERM + 1);
  476. tap_key(left_shift);
  477. EXPECT_EQ(is_caps_word_on(), false); // Caps Word is still off.
  478. clear_oneshot_mods();
  479. testing::Mock::VerifyAndClearExpectations(&driver);
  480. }
  481. // clang-format off
  482. INSTANTIATE_TEST_CASE_P(
  483. Shifts,
  484. CapsWordDoubleTapShift,
  485. ::testing::Values(
  486. CapsWordDoubleTapShiftParams{"PlainShift", KC_LSFT},
  487. CapsWordDoubleTapShiftParams{"OneshotShift", OSM(MOD_LSFT)}
  488. ),
  489. CapsWordDoubleTapShiftParams::GetName
  490. );
  491. // clang-format on
  492. } // namespace