qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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 }