Parent directory

test_one_shot_keys.cpp

10501 bytes
  1/* Copyright 2021 Stefan Kerkmann
  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 "action_util.h"
 18#include "keyboard_report_util.hpp"
 19#include "test_common.hpp"
 20
 21using testing::_;
 22using testing::InSequence;
 23
 24class OneShot : public TestFixture {};
 25class OneShotParametrizedTestFixture : public ::testing::WithParamInterface<std::pair<KeymapKey, KeymapKey>>, public OneShot {};
 26
 27TEST_F(OneShot, OSMWithoutAdditionalKeypressDoesNothing) {
 28    TestDriver driver;
 29    auto       osm_key = KeymapKey(0, 0, 0, OSM(MOD_LSFT), KC_LSFT);
 30
 31    set_keymap({osm_key});
 32
 33    /* Press and release OSM key*/
 34    EXPECT_NO_REPORT(driver);
 35    tap_key(osm_key);
 36    VERIFY_AND_CLEAR(driver);
 37
 38    /* OSM are added when an actual report is send */
 39    EXPECT_REPORT(driver, (osm_key.report_code));
 40    send_keyboard_report();
 41    VERIFY_AND_CLEAR(driver);
 42
 43    /* Make unit-test pass */
 44    clear_oneshot_mods();
 45}
 46
 47#if defined(ONESHOT_TIMEOUT)
 48
 49TEST_P(OneShotParametrizedTestFixture, OSMExpiredDoesNothing) {
 50    TestDriver driver;
 51    KeymapKey  osm_key     = GetParam().first;
 52    KeymapKey  regular_key = GetParam().second;
 53
 54    set_keymap({osm_key, regular_key});
 55
 56    /* Press and release OSM */
 57    EXPECT_NO_REPORT(driver);
 58    osm_key.press();
 59    run_one_scan_loop();
 60    osm_key.release();
 61    idle_for(ONESHOT_TIMEOUT);
 62    VERIFY_AND_CLEAR(driver);
 63
 64    /* Press regular key */
 65    EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
 66    regular_key.press();
 67    run_one_scan_loop();
 68    VERIFY_AND_CLEAR(driver);
 69
 70    /* Release regular key */
 71    EXPECT_EMPTY_REPORT(driver);
 72    regular_key.release();
 73    run_one_scan_loop();
 74    VERIFY_AND_CLEAR(driver);
 75}
 76
 77#endif
 78
 79TEST_P(OneShotParametrizedTestFixture, OSMWithAdditionalKeypress) {
 80    TestDriver driver;
 81    KeymapKey  osm_key     = GetParam().first;
 82    KeymapKey  regular_key = GetParam().second;
 83
 84    set_keymap({osm_key, regular_key});
 85
 86    /* Press and release OSM */
 87    EXPECT_NO_REPORT(driver);
 88    tap_key(osm_key);
 89    VERIFY_AND_CLEAR(driver);
 90
 91    /* Press regular key */
 92    EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
 93    regular_key.press();
 94    run_one_scan_loop();
 95    VERIFY_AND_CLEAR(driver);
 96
 97    /* Release regular key */
 98    EXPECT_EMPTY_REPORT(driver);
 99    regular_key.release();
100    run_one_scan_loop();
101    VERIFY_AND_CLEAR(driver);
102}
103
104TEST_P(OneShotParametrizedTestFixture, OSMAsRegularModifierWithAdditionalKeypress) {
105    TestDriver          driver;
106    testing::InSequence s;
107
108    KeymapKey osm_key     = GetParam().first;
109    KeymapKey regular_key = GetParam().second;
110
111    set_keymap({osm_key, regular_key});
112
113    /* Press OSM */
114    EXPECT_NO_REPORT(driver);
115    osm_key.press();
116    run_one_scan_loop();
117    VERIFY_AND_CLEAR(driver);
118
119    /* Press regular key */
120    EXPECT_NO_REPORT(driver);
121    regular_key.press();
122    run_one_scan_loop();
123    VERIFY_AND_CLEAR(driver);
124
125    /* Release regular key */
126    EXPECT_NO_REPORT(driver);
127    regular_key.release();
128    run_one_scan_loop();
129    VERIFY_AND_CLEAR(driver);
130
131    /* Release OSM */
132    EXPECT_REPORT(driver, (regular_key.report_code, osm_key.report_code)).Times(1);
133    EXPECT_EMPTY_REPORT(driver);
134    osm_key.release();
135    run_one_scan_loop();
136    VERIFY_AND_CLEAR(driver);
137}
138
139// clang-format off
140
141INSTANTIATE_TEST_CASE_P(
142    OneShotModifierTests,
143    OneShotParametrizedTestFixture,
144    ::testing::Values(
145        /* first is osm key, second is regular key. */
146        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT}, KeymapKey{0, 1, 1, KC_A}),
147        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LCTL), KC_LCTL}, KeymapKey{0, 1, 1, KC_A}),
148        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LALT), KC_LALT}, KeymapKey{0, 1, 1, KC_A}),
149        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_LGUI), KC_LGUI}, KeymapKey{0, 1, 1, KC_A}),
150        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RCTL), KC_RCTL}, KeymapKey{0, 1, 1, KC_A}),
151        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RSFT), KC_RSFT}, KeymapKey{0, 1, 1, KC_A}),
152        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RALT), KC_RALT}, KeymapKey{0, 1, 1, KC_A}),
153        std::make_pair(KeymapKey{0, 0, 0, OSM(MOD_RGUI), KC_RGUI}, KeymapKey{0, 1, 1, KC_A})
154        ));
155// clang-format on
156
157TEST_F(OneShot, OSMChainingTwoOSMs) {
158    TestDriver driver;
159    InSequence s;
160    KeymapKey  osm_key1    = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
161    KeymapKey  osm_key2    = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
162    KeymapKey  regular_key = KeymapKey{0, 1, 0, KC_A};
163
164    set_keymap({osm_key1, osm_key2, regular_key});
165
166    /* Press and release OSM1 */
167    EXPECT_NO_REPORT(driver);
168    tap_key(osm_key1);
169    VERIFY_AND_CLEAR(driver);
170
171    /* Press and relesea OSM2 */
172    EXPECT_NO_REPORT(driver);
173    tap_key(osm_key2);
174    VERIFY_AND_CLEAR(driver);
175
176    /* Press regular key */
177    EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
178    regular_key.press();
179    run_one_scan_loop();
180    VERIFY_AND_CLEAR(driver);
181
182    /* Release regular key */
183    EXPECT_EMPTY_REPORT(driver);
184    regular_key.release();
185    run_one_scan_loop();
186    VERIFY_AND_CLEAR(driver);
187}
188
189TEST_F(OneShot, OSMDoubleTapNotLockingOSMs) {
190    TestDriver driver;
191    InSequence s;
192    KeymapKey  osm_key1    = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
193    KeymapKey  osm_key2    = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
194    KeymapKey  regular_key = KeymapKey{0, 1, 0, KC_A};
195
196    set_keymap({osm_key1, osm_key2, regular_key});
197
198    /* Press and release OSM1 */
199    EXPECT_NO_REPORT(driver);
200    tap_key(osm_key1);
201    VERIFY_AND_CLEAR(driver);
202
203    /* Press and release OSM2 twice */
204    EXPECT_NO_REPORT(driver);
205    tap_key(osm_key2);
206    tap_key(osm_key2);
207    VERIFY_AND_CLEAR(driver);
208
209    /* Press regular key */
210    EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
211    regular_key.press();
212    run_one_scan_loop();
213    VERIFY_AND_CLEAR(driver);
214
215    /* Release regular key */
216    EXPECT_EMPTY_REPORT(driver);
217    regular_key.release();
218    run_one_scan_loop();
219    VERIFY_AND_CLEAR(driver);
220
221    /* Press regular key */
222    EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
223    regular_key.press();
224    run_one_scan_loop();
225    VERIFY_AND_CLEAR(driver);
226
227    /* Release regular key */
228    EXPECT_EMPTY_REPORT(driver);
229    regular_key.release();
230    run_one_scan_loop();
231    VERIFY_AND_CLEAR(driver);
232}
233
234TEST_F(OneShot, OSMHoldNotLockingOSMs) {
235    TestDriver driver;
236    InSequence s;
237    KeymapKey  osm_key1    = KeymapKey{0, 0, 0, OSM(MOD_LSFT), KC_LSFT};
238    KeymapKey  osm_key2    = KeymapKey{0, 0, 1, OSM(MOD_LCTL), KC_LCTL};
239    KeymapKey  regular_key = KeymapKey{0, 1, 0, KC_A};
240
241    set_keymap({osm_key1, osm_key2, regular_key});
242
243    /* Press and release OSM1 */
244    EXPECT_NO_REPORT(driver);
245    tap_key(osm_key1);
246    VERIFY_AND_CLEAR(driver);
247
248    /* Press and hold OSM2 */
249    EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code)).Times(1);
250    osm_key2.press();
251    run_one_scan_loop();
252    idle_for(TAPPING_TERM);
253    VERIFY_AND_CLEAR(driver);
254
255    /* Press and release regular key */
256    EXPECT_REPORT(driver, (osm_key1.report_code, osm_key2.report_code, regular_key.report_code)).Times(1);
257    EXPECT_REPORT(driver, (osm_key2.report_code)).Times(1);
258    tap_key(regular_key);
259    VERIFY_AND_CLEAR(driver);
260
261    /* Release OSM2 */
262    EXPECT_EMPTY_REPORT(driver);
263    osm_key2.release();
264    run_one_scan_loop();
265    VERIFY_AND_CLEAR(driver);
266
267    /* Press regular key */
268    EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
269    regular_key.press();
270    run_one_scan_loop();
271    VERIFY_AND_CLEAR(driver);
272
273    /* Release regular key */
274    EXPECT_EMPTY_REPORT(driver);
275    regular_key.release();
276    run_one_scan_loop();
277    VERIFY_AND_CLEAR(driver);
278}
279
280TEST_F(OneShot, OSLWithAdditionalKeypress) {
281    TestDriver driver;
282    InSequence s;
283    KeymapKey  osl_key     = KeymapKey{0, 0, 0, OSL(1)};
284    KeymapKey  regular_key = KeymapKey{1, 1, 0, KC_A};
285
286    set_keymap({osl_key, regular_key});
287
288    /* Press OSL key */
289    EXPECT_NO_REPORT(driver);
290    osl_key.press();
291    run_one_scan_loop();
292    VERIFY_AND_CLEAR(driver);
293
294    /* Release OSL key */
295    EXPECT_NO_REPORT(driver);
296    osl_key.release();
297    run_one_scan_loop();
298    VERIFY_AND_CLEAR(driver);
299
300    /* Press regular key */
301    EXPECT_REPORT(driver, (regular_key.report_code)).Times(1);
302    EXPECT_EMPTY_REPORT(driver);
303    regular_key.press();
304    run_one_scan_loop();
305    VERIFY_AND_CLEAR(driver);
306
307    /* Release regular key */
308    EXPECT_NO_REPORT(driver);
309    regular_key.release();
310    run_one_scan_loop();
311    VERIFY_AND_CLEAR(driver);
312}
313
314TEST_F(OneShot, OSLWithOsmAndAdditionalKeypress) {
315    TestDriver driver;
316    InSequence s;
317    KeymapKey  osl_key     = KeymapKey{0, 0, 0, OSL(1)};
318    KeymapKey  osm_key     = KeymapKey{1, 1, 0, OSM(MOD_LSFT), KC_LSFT};
319    KeymapKey  regular_key = KeymapKey{1, 1, 1, KC_A};
320
321    set_keymap({osl_key, osm_key, regular_key});
322
323    /* Press OSL key */
324    EXPECT_NO_REPORT(driver);
325    osl_key.press();
326    run_one_scan_loop();
327    VERIFY_AND_CLEAR(driver);
328
329    /* Release OSL key */
330    EXPECT_NO_REPORT(driver);
331    osl_key.release();
332    run_one_scan_loop();
333    EXPECT_TRUE(layer_state_is(1));
334    VERIFY_AND_CLEAR(driver);
335
336    /* Press and release OSM */
337    EXPECT_NO_REPORT(driver);
338    tap_key(osm_key);
339    EXPECT_TRUE(layer_state_is(1));
340    VERIFY_AND_CLEAR(driver);
341
342    /* Press regular key */
343    EXPECT_REPORT(driver, (osm_key.report_code, regular_key.report_code)).Times(1);
344    EXPECT_EMPTY_REPORT(driver);
345    regular_key.press();
346    run_one_scan_loop();
347    EXPECT_FALSE(layer_state_is(1));
348    VERIFY_AND_CLEAR(driver);
349
350    /* Release regular key */
351    EXPECT_NO_REPORT(driver);
352    regular_key.release();
353    run_one_scan_loop();
354    VERIFY_AND_CLEAR(driver);
355}