test_examples.cpp
11822 bytes
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
24using testing::_;
25using testing::InSequence;
26
27class TapDance : public TestFixture {};
28
29TEST_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
59TEST_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
102TEST_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
133TEST_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
177TEST_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
219TEST_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
257TEST_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
320TEST_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
392TEST_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}