Parent directory

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}