test_tapping.cpp
5781 bytes
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
23using testing::_;
24using testing::InSequence;
25
26class Tapping : public TestFixture {};
27
28TEST_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
49TEST_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
70TEST_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
125TEST_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
159TEST_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}