test_examples.cpp (11822B)
1 /* Copyright 2022 Jouke Witteveen 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 "keyboard_report_util.hpp" 18 #include "keycode.h" 19 #include "test_common.hpp" 20 #include "action_tapping.h" 21 #include "test_keymap_key.hpp" 22 #include "examples.h" 23 24 using testing::_; 25 using testing::InSequence; 26 27 class TapDance : public TestFixture {}; 28 29 TEST_F(TapDance, DoubleTap) { 30 TestDriver driver; 31 InSequence s; 32 auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)}; 33 34 set_keymap({key_esc_caps}); 35 36 /* The tap dance key does nothing on the first press */ 37 key_esc_caps.press(); 38 run_one_scan_loop(); 39 key_esc_caps.release(); 40 EXPECT_NO_REPORT(driver); 41 42 /* We get the key press and the release on timeout */ 43 idle_for(TAPPING_TERM); 44 EXPECT_REPORT(driver, (KC_ESC)); 45 EXPECT_EMPTY_REPORT(driver); 46 run_one_scan_loop(); 47 48 /* Double tap gets us the second key */ 49 tap_key(key_esc_caps); 50 EXPECT_NO_REPORT(driver); 51 key_esc_caps.press(); 52 EXPECT_REPORT(driver, (KC_CAPS)); 53 run_one_scan_loop(); 54 key_esc_caps.release(); 55 EXPECT_EMPTY_REPORT(driver); 56 run_one_scan_loop(); 57 } 58 59 TEST_F(TapDance, DoubleTapWithMod) { 60 TestDriver driver; 61 InSequence s; 62 auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)}; 63 auto key_shift = KeymapKey{0, 2, 0, KC_LSFT}; 64 65 set_keymap({key_esc_caps, key_shift}); 66 67 /* The tap dance key does nothing on the first press */ 68 key_shift.press(); 69 EXPECT_REPORT(driver, (KC_LSFT)); 70 run_one_scan_loop(); 71 key_esc_caps.press(); 72 run_one_scan_loop(); 73 74 key_esc_caps.release(); 75 key_shift.release(); 76 EXPECT_EMPTY_REPORT(driver); 77 78 /* We get the key press and the release */ 79 idle_for(TAPPING_TERM); 80 EXPECT_REPORT(driver, (KC_LSFT)); 81 EXPECT_REPORT(driver, (KC_LSFT, KC_ESC)); 82 EXPECT_REPORT(driver, (KC_LSFT)); 83 EXPECT_EMPTY_REPORT(driver); 84 run_one_scan_loop(); 85 86 /* Double tap gets us the second key */ 87 key_shift.press(); 88 EXPECT_REPORT(driver, (KC_LSFT)); 89 run_one_scan_loop(); 90 tap_key(key_esc_caps); 91 EXPECT_NO_REPORT(driver); 92 key_shift.release(); 93 key_esc_caps.press(); 94 EXPECT_REPORT(driver, (KC_LSFT, KC_CAPS)); 95 EXPECT_REPORT(driver, (KC_CAPS)); 96 run_one_scan_loop(); 97 key_esc_caps.release(); 98 EXPECT_EMPTY_REPORT(driver); 99 run_one_scan_loop(); 100 } 101 102 TEST_F(TapDance, DoubleTapInterrupted) { 103 TestDriver driver; 104 InSequence s; 105 auto key_esc_caps = KeymapKey{0, 1, 0, TD(TD_ESC_CAPS)}; 106 auto regular_key = KeymapKey(0, 2, 0, KC_A); 107 108 set_keymap({key_esc_caps, regular_key}); 109 110 /* Interrupted double tap */ 111 tap_key(key_esc_caps); 112 regular_key.press(); 113 /* Immediate tap of the first key */ 114 EXPECT_REPORT(driver, (KC_ESC)); 115 EXPECT_EMPTY_REPORT(driver); 116 /* Followed by the interrupting key */ 117 EXPECT_REPORT(driver, (KC_A)); 118 run_one_scan_loop(); 119 regular_key.release(); 120 EXPECT_EMPTY_REPORT(driver); 121 run_one_scan_loop(); 122 123 /* Second tap after being interrupted acts as a single tap */ 124 key_esc_caps.press(); 125 run_one_scan_loop(); 126 key_esc_caps.release(); 127 idle_for(TAPPING_TERM); 128 EXPECT_REPORT(driver, (KC_ESC)); 129 EXPECT_EMPTY_REPORT(driver); 130 run_one_scan_loop(); 131 } 132 133 TEST_F(TapDance, DanceFn) { 134 TestDriver driver; 135 InSequence s; 136 auto key_egg = KeymapKey(0, 1, 0, TD(CT_EGG)); 137 138 set_keymap({key_egg}); 139 140 /* 99 taps do nothing */ 141 for (int i = 0; i < 99; i++) { 142 run_one_scan_loop(); 143 key_egg.press(); 144 run_one_scan_loop(); 145 key_egg.release(); 146 } 147 idle_for(TAPPING_TERM); 148 EXPECT_NO_REPORT(driver); 149 run_one_scan_loop(); 150 151 /* 100 taps trigger the action */ 152 for (int i = 0; i < 100; i++) { 153 run_one_scan_loop(); 154 key_egg.press(); 155 run_one_scan_loop(); 156 key_egg.release(); 157 } 158 idle_for(TAPPING_TERM); 159 EXPECT_REPORT(driver, (KC_C)); 160 EXPECT_EMPTY_REPORT(driver); 161 run_one_scan_loop(); 162 163 /* 250 taps act the same as 100 taps */ 164 /* Taps are counted in an uint8_t, so the count overflows after 255 taps */ 165 for (int i = 0; i < 250; i++) { 166 run_one_scan_loop(); 167 key_egg.press(); 168 run_one_scan_loop(); 169 key_egg.release(); 170 } 171 idle_for(TAPPING_TERM); 172 EXPECT_REPORT(driver, (KC_C)); 173 EXPECT_EMPTY_REPORT(driver); 174 run_one_scan_loop(); 175 } 176 177 TEST_F(TapDance, DanceFnAdvanced) { 178 TestDriver driver; 179 InSequence s; 180 auto key_flsh = KeymapKey(0, 1, 0, TD(CT_FLSH)); 181 182 set_keymap({key_flsh}); 183 184 /* Three taps don't trigger a reset */ 185 EXPECT_REPORT(driver, (KC_3)); 186 EXPECT_REPORT(driver, (KC_3, KC_2)); 187 EXPECT_REPORT(driver, (KC_3, KC_2, KC_1)); 188 for (int i = 0; i < 3; i++) { 189 run_one_scan_loop(); 190 key_flsh.press(); 191 run_one_scan_loop(); 192 key_flsh.release(); 193 } 194 idle_for(TAPPING_TERM); 195 EXPECT_REPORT(driver, (KC_3, KC_2)); 196 EXPECT_REPORT(driver, (KC_3)); 197 EXPECT_EMPTY_REPORT(driver); 198 run_one_scan_loop(); 199 200 /* Four taps trigger a reset */ 201 EXPECT_REPORT(driver, (KC_3)); 202 EXPECT_REPORT(driver, (KC_3, KC_2)); 203 EXPECT_REPORT(driver, (KC_3, KC_2, KC_1)); 204 EXPECT_REPORT(driver, (KC_2, KC_1)); 205 EXPECT_REPORT(driver, (KC_1)); 206 EXPECT_EMPTY_REPORT(driver); 207 for (int i = 0; i < 4; i++) { 208 run_one_scan_loop(); 209 key_flsh.press(); 210 run_one_scan_loop(); 211 key_flsh.release(); 212 } 213 idle_for(TAPPING_TERM); 214 EXPECT_REPORT(driver, (KC_R)); 215 EXPECT_EMPTY_REPORT(driver); 216 run_one_scan_loop(); 217 } 218 219 TEST_F(TapDance, TapHold) { 220 TestDriver driver; 221 InSequence s; 222 auto key_cln = KeymapKey{0, 1, 0, TD(CT_CLN)}; 223 224 set_keymap({key_cln}); 225 226 /* Short taps fire on release */ 227 key_cln.press(); 228 run_one_scan_loop(); 229 key_cln.release(); 230 EXPECT_REPORT(driver, (KC_LSFT)); 231 EXPECT_REPORT(driver, (KC_LSFT, KC_SCLN)); 232 EXPECT_REPORT(driver, (KC_LSFT)); 233 EXPECT_EMPTY_REPORT(driver); 234 run_one_scan_loop(); 235 236 /* Holds immediate following a tap apply to the tap key */ 237 key_cln.press(); 238 EXPECT_REPORT(driver, (KC_LSFT)); 239 EXPECT_REPORT(driver, (KC_LSFT, KC_SCLN)); 240 idle_for(TAPPING_TERM * 2); 241 key_cln.release(); 242 EXPECT_REPORT(driver, (KC_LSFT)); 243 EXPECT_EMPTY_REPORT(driver); 244 run_one_scan_loop(); 245 246 /* Holds trigger the hold key */ 247 key_cln.press(); 248 idle_for(TAPPING_TERM); 249 run_one_scan_loop(); 250 EXPECT_REPORT(driver, (KC_SCLN)); 251 run_one_scan_loop(); 252 key_cln.release(); 253 EXPECT_EMPTY_REPORT(driver); 254 run_one_scan_loop(); 255 } 256 257 TEST_F(TapDance, QuadFunction) { 258 TestDriver driver; 259 InSequence s; 260 auto key_quad = KeymapKey{0, 1, 0, TD(X_CTL)}; 261 auto regular_key = KeymapKey(0, 2, 0, KC_A); 262 263 set_keymap({key_quad, regular_key}); 264 265 /* Single tap */ 266 key_quad.press(); 267 run_one_scan_loop(); 268 key_quad.release(); 269 idle_for(TAPPING_TERM); 270 EXPECT_REPORT(driver, (KC_X)); 271 EXPECT_EMPTY_REPORT(driver); 272 run_one_scan_loop(); 273 274 /* Single hold */ 275 key_quad.press(); 276 run_one_scan_loop(); 277 idle_for(TAPPING_TERM); 278 EXPECT_REPORT(driver, (KC_LCTL)); 279 run_one_scan_loop(); 280 key_quad.release(); 281 EXPECT_EMPTY_REPORT(driver); 282 run_one_scan_loop(); 283 284 /* Double tap */ 285 tap_key(key_quad); 286 key_quad.press(); 287 run_one_scan_loop(); 288 key_quad.release(); 289 idle_for(TAPPING_TERM); 290 EXPECT_REPORT(driver, (KC_ESC)); 291 EXPECT_EMPTY_REPORT(driver); 292 run_one_scan_loop(); 293 294 /* Double tap and hold */ 295 tap_key(key_quad); 296 key_quad.press(); 297 run_one_scan_loop(); 298 idle_for(TAPPING_TERM); 299 EXPECT_REPORT(driver, (KC_LALT)); 300 run_one_scan_loop(); 301 key_quad.release(); 302 EXPECT_EMPTY_REPORT(driver); 303 run_one_scan_loop(); 304 305 /* Double single tap */ 306 tap_key(key_quad); 307 tap_key(key_quad); 308 regular_key.press(); 309 EXPECT_REPORT(driver, (KC_X)); 310 EXPECT_EMPTY_REPORT(driver); 311 EXPECT_REPORT(driver, (KC_X)); 312 EXPECT_EMPTY_REPORT(driver); 313 EXPECT_REPORT(driver, (KC_A)); 314 run_one_scan_loop(); 315 regular_key.release(); 316 EXPECT_EMPTY_REPORT(driver); 317 run_one_scan_loop(); 318 } 319 320 TEST_F(TapDance, DanceFnAdvancedWithRelease) { 321 TestDriver driver; 322 InSequence s; 323 auto key_rls = KeymapKey(0, 1, 0, TD(TD_RELEASE)); 324 325 set_keymap({key_rls}); 326 327 /* Single press and unpress */ 328 key_rls.press(); 329 EXPECT_REPORT(driver, (KC_P)); 330 EXPECT_EMPTY_REPORT(driver); 331 run_one_scan_loop(); 332 333 key_rls.release(); 334 EXPECT_REPORT(driver, (KC_U)); 335 EXPECT_EMPTY_REPORT(driver); 336 run_one_scan_loop(); 337 338 EXPECT_REPORT(driver, (KC_F)); 339 EXPECT_EMPTY_REPORT(driver); 340 EXPECT_REPORT(driver, (KC_R)); 341 EXPECT_EMPTY_REPORT(driver); 342 idle_for(TAPPING_TERM); 343 run_one_scan_loop(); 344 345 /* Double press and unpress */ 346 key_rls.press(); 347 EXPECT_REPORT(driver, (KC_P)); 348 EXPECT_EMPTY_REPORT(driver); 349 run_one_scan_loop(); 350 351 key_rls.release(); 352 EXPECT_REPORT(driver, (KC_U)); 353 EXPECT_EMPTY_REPORT(driver); 354 run_one_scan_loop(); 355 356 key_rls.press(); 357 EXPECT_REPORT(driver, (KC_P)); 358 EXPECT_EMPTY_REPORT(driver); 359 run_one_scan_loop(); 360 361 key_rls.release(); 362 EXPECT_REPORT(driver, (KC_U)); 363 EXPECT_EMPTY_REPORT(driver); 364 run_one_scan_loop(); 365 366 EXPECT_REPORT(driver, (KC_F)); 367 EXPECT_EMPTY_REPORT(driver); 368 EXPECT_REPORT(driver, (KC_R)); 369 EXPECT_EMPTY_REPORT(driver); 370 idle_for(TAPPING_TERM); 371 run_one_scan_loop(); 372 373 /* Unpress after tapping term has elapsed (key is registered as held) */ 374 key_rls.press(); 375 EXPECT_REPORT(driver, (KC_P)); 376 EXPECT_EMPTY_REPORT(driver); 377 run_one_scan_loop(); 378 379 EXPECT_REPORT(driver, (KC_F)); 380 EXPECT_EMPTY_REPORT(driver); 381 idle_for(TAPPING_TERM); 382 run_one_scan_loop(); 383 384 key_rls.release(); 385 EXPECT_REPORT(driver, (KC_U)); 386 EXPECT_EMPTY_REPORT(driver); 387 EXPECT_REPORT(driver, (KC_R)); 388 EXPECT_EMPTY_REPORT(driver); 389 run_one_scan_loop(); 390 } 391 392 TEST_F(TapDance, DanceFnAdvancedWithReleaseAndFinish) { 393 TestDriver driver; 394 InSequence s; 395 auto key_rls = KeymapKey(0, 1, 0, TD(TD_RELEASE_AND_FINISH)); 396 397 set_keymap({key_rls}); 398 399 /* Single press and unpress */ 400 key_rls.press(); 401 EXPECT_REPORT(driver, (KC_P)); 402 EXPECT_EMPTY_REPORT(driver); 403 run_one_scan_loop(); 404 405 key_rls.release(); 406 EXPECT_REPORT(driver, (KC_U)); 407 EXPECT_EMPTY_REPORT(driver); 408 EXPECT_REPORT(driver, (KC_R)); 409 EXPECT_EMPTY_REPORT(driver); 410 run_one_scan_loop(); 411 412 // Verify the finished and/or reset functions aren't called 413 // after the tapping term elapses 414 idle_for(TAPPING_TERM); 415 run_one_scan_loop(); 416 417 /* Unpress after tapping term has elapsed (key is registered as held) */ 418 key_rls.press(); 419 EXPECT_REPORT(driver, (KC_P)); 420 EXPECT_EMPTY_REPORT(driver); 421 run_one_scan_loop(); 422 423 EXPECT_REPORT(driver, (KC_F)); 424 EXPECT_EMPTY_REPORT(driver); 425 idle_for(TAPPING_TERM); 426 run_one_scan_loop(); 427 428 key_rls.release(); 429 EXPECT_REPORT(driver, (KC_U)); 430 EXPECT_EMPTY_REPORT(driver); 431 EXPECT_REPORT(driver, (KC_R)); 432 EXPECT_EMPTY_REPORT(driver); 433 run_one_scan_loop(); 434 }