test_tapping.cpp (5781B)
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 "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 23 using testing::_; 24 using testing::InSequence; 25 26 class Tapping : public TestFixture {}; 27 28 TEST_F(Tapping, TapA_SHFT_T_KeyReportsKey) { 29 TestDriver driver; 30 InSequence s; 31 auto key_shift_hold_p_tap = KeymapKey(0, 7, 0, SFT_T(KC_P)); 32 33 set_keymap({key_shift_hold_p_tap}); 34 35 // Tapping keys does nothing on press 36 key_shift_hold_p_tap.press(); 37 EXPECT_NO_REPORT(driver); 38 run_one_scan_loop(); 39 40 // First we get the key press 41 key_shift_hold_p_tap.release(); 42 EXPECT_REPORT(driver, (KC_P)); 43 44 // Then the release 45 EXPECT_EMPTY_REPORT(driver); 46 run_one_scan_loop(); 47 } 48 49 TEST_F(Tapping, HoldA_SHFT_T_KeyReportsShift) { 50 TestDriver driver; 51 InSequence s; 52 auto mod_tap_hold_key = KeymapKey(0, 7, 0, SFT_T(KC_P)); 53 54 set_keymap({mod_tap_hold_key}); 55 56 mod_tap_hold_key.press(); 57 58 // Tapping keys does nothing on press 59 EXPECT_NO_REPORT(driver); 60 idle_for(TAPPING_TERM); 61 62 EXPECT_REPORT(driver, (KC_LSFT)); 63 run_one_scan_loop(); 64 65 EXPECT_EMPTY_REPORT(driver); 66 mod_tap_hold_key.release(); 67 run_one_scan_loop(); 68 } 69 70 TEST_F(Tapping, ANewTapWithinTappingTermIsBuggy) { 71 // See issue #1478 for more information 72 TestDriver driver; 73 InSequence s; 74 auto key_shift_hold_p_tap = KeymapKey(0, 7, 0, SFT_T(KC_P)); 75 76 set_keymap({key_shift_hold_p_tap}); 77 78 // Tapping keys does nothing on press 79 key_shift_hold_p_tap.press(); 80 EXPECT_NO_REPORT(driver); 81 run_one_scan_loop(); 82 key_shift_hold_p_tap.release(); 83 84 // First we get the key press 85 EXPECT_REPORT(driver, (KC_P)); 86 // Then the release 87 EXPECT_EMPTY_REPORT(driver); 88 run_one_scan_loop(); 89 90 // This sends KC_P, even if it should do nothing 91 key_shift_hold_p_tap.press(); 92 // This test should not succed if everything works correctly 93 EXPECT_REPORT(driver, (KC_P)); 94 run_one_scan_loop(); 95 96 key_shift_hold_p_tap.release(); 97 EXPECT_EMPTY_REPORT(driver); 98 idle_for(TAPPING_TERM + 1); 99 100 // On the other hand, nothing is sent if we are outside the tapping term 101 key_shift_hold_p_tap.press(); 102 EXPECT_NO_REPORT(driver); 103 run_one_scan_loop(); 104 key_shift_hold_p_tap.release(); 105 106 // First we get the key press 107 EXPECT_REPORT(driver, (KC_P)); 108 // Then the release 109 EXPECT_EMPTY_REPORT(driver); 110 idle_for(TAPPING_TERM + 1); 111 112 // Now we are geting into strange territory, as the hold registers too early here 113 // But the stranges part is: 114 // If TAPPING_TERM + 1 above is changed to TAPPING_TERM or TAPPING_TERM + 2 it doesn't 115 key_shift_hold_p_tap.press(); 116 // Shouldn't be called here really 117 EXPECT_REPORT(driver, (KC_LEFT_SHIFT)).Times(1); 118 idle_for(TAPPING_TERM); 119 120 EXPECT_EMPTY_REPORT(driver); 121 key_shift_hold_p_tap.release(); 122 run_one_scan_loop(); 123 } 124 125 TEST_F(Tapping, TapA_CTL_T_KeyWhileReleasingShift) { 126 TestDriver driver; 127 InSequence s; 128 auto shift_key = KeymapKey(0, 7, 0, KC_LSFT); 129 auto mod_tap_hold_key = KeymapKey(0, 8, 0, CTL_T(KC_P)); 130 131 set_keymap({shift_key, mod_tap_hold_key}); 132 133 shift_key.press(); 134 // Shift is reported 135 EXPECT_REPORT(driver, (KC_LSFT)); 136 run_one_scan_loop(); 137 VERIFY_AND_CLEAR(driver); 138 139 mod_tap_hold_key.press(); 140 // Tapping keys does nothing on press 141 EXPECT_NO_REPORT(driver); 142 run_one_scan_loop(); 143 144 shift_key.release(); 145 // Releasing shift is delayed while tapping is in progress 146 EXPECT_NO_REPORT(driver); 147 run_one_scan_loop(); 148 VERIFY_AND_CLEAR(driver); 149 150 mod_tap_hold_key.release(); 151 // Releasing mod-tap key reports the tap and releases shift 152 EXPECT_REPORT(driver, (KC_LSFT, KC_P)); 153 EXPECT_REPORT(driver, (KC_P)); 154 EXPECT_EMPTY_REPORT(driver); 155 run_one_scan_loop(); 156 VERIFY_AND_CLEAR(driver); 157 } 158 159 TEST_F(Tapping, TapA_CTL_T_KeyWhileReleasingLayer) { 160 TestDriver driver; 161 InSequence s; 162 auto layer_key = KeymapKey(0, 7, 0, MO(1)); 163 auto trans_key = KeymapKey(1, 7, 0, KC_TRNS); 164 auto mod_tap_hold_key0 = KeymapKey(0, 8, 0, CTL_T(KC_P)); 165 auto mod_tap_hold_key1 = KeymapKey(1, 8, 0, CTL_T(KC_Q)); 166 167 set_keymap({layer_key, trans_key, mod_tap_hold_key0, mod_tap_hold_key1}); 168 169 layer_key.press(); 170 // Pressing the layer key does nothing 171 EXPECT_NO_REPORT(driver); 172 run_one_scan_loop(); 173 174 mod_tap_hold_key1.press(); 175 // Tapping layer 1 mod-tap key does nothing on press 176 EXPECT_NO_REPORT(driver); 177 run_one_scan_loop(); 178 179 layer_key.release(); 180 // Releasing layer is delayed while tapping is in progress 181 EXPECT_NO_REPORT(driver); 182 run_one_scan_loop(); 183 VERIFY_AND_CLEAR(driver); 184 185 mod_tap_hold_key1.release(); 186 // Releasing mod-tap key reports the tap of the layer 1 key 187 // If delayed layer release is broken, this reports the layer 0 key 188 EXPECT_REPORT(driver, (KC_Q)); 189 EXPECT_EMPTY_REPORT(driver); 190 run_one_scan_loop(); 191 VERIFY_AND_CLEAR(driver); 192 }