Improve test invocation, fix Retro Shift bugs, and add Auto+Retro Shift test cases (#15889)
parent
1fb02d5ad8
commit
dd94877ec6
26
Makefile
26
Makefile
|
@ -300,17 +300,18 @@ endef
|
||||||
define BUILD_TEST
|
define BUILD_TEST
|
||||||
TEST_PATH := $1
|
TEST_PATH := $1
|
||||||
TEST_NAME := $$(notdir $$(TEST_PATH))
|
TEST_NAME := $$(notdir $$(TEST_PATH))
|
||||||
|
TEST_FULL_NAME := $$(subst /,_,$$(patsubst $$(ROOT_DIR)tests/%,%,$$(TEST_PATH)))
|
||||||
MAKE_TARGET := $2
|
MAKE_TARGET := $2
|
||||||
COMMAND := $1
|
COMMAND := $1
|
||||||
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_test.mk $$(MAKE_TARGET)
|
MAKE_CMD := $$(MAKE) -r -R -C $(ROOT_DIR) -f $(BUILDDEFS_PATH)/build_test.mk $$(MAKE_TARGET)
|
||||||
MAKE_VARS := TEST=$$(TEST_NAME) TEST_PATH=$$(TEST_PATH) FULL_TESTS="$$(FULL_TESTS)"
|
MAKE_VARS := TEST=$$(TEST_NAME) TEST_OUTPUT=$$(TEST_FULL_NAME) TEST_PATH=$$(TEST_PATH) FULL_TESTS="$$(FULL_TESTS)"
|
||||||
MAKE_MSG := $$(MSG_MAKE_TEST)
|
MAKE_MSG := $$(MSG_MAKE_TEST)
|
||||||
$$(eval $$(call BUILD))
|
$$(eval $$(call BUILD))
|
||||||
ifneq ($$(MAKE_TARGET),clean)
|
ifneq ($$(MAKE_TARGET),clean)
|
||||||
TEST_EXECUTABLE := $$(TEST_OUTPUT_DIR)/$$(TEST_NAME).elf
|
TEST_EXECUTABLE := $$(TEST_OUTPUT_DIR)/$$(TEST_FULL_NAME).elf
|
||||||
TESTS += $$(TEST_NAME)
|
TESTS += $$(TEST_FULL_NAME)
|
||||||
TEST_MSG := $$(MSG_TEST)
|
TEST_MSG := $$(MSG_TEST)
|
||||||
$$(TEST_NAME)_COMMAND := \
|
$$(TEST_FULL_NAME)_COMMAND := \
|
||||||
printf "$$(TEST_MSG)\n"; \
|
printf "$$(TEST_MSG)\n"; \
|
||||||
$$(TEST_EXECUTABLE); \
|
$$(TEST_EXECUTABLE); \
|
||||||
if [ $$$$? -gt 0 ]; \
|
if [ $$$$? -gt 0 ]; \
|
||||||
|
@ -322,15 +323,22 @@ endef
|
||||||
|
|
||||||
define PARSE_TEST
|
define PARSE_TEST
|
||||||
TESTS :=
|
TESTS :=
|
||||||
TEST_NAME := $$(firstword $$(subst :, ,$$(RULE)))
|
# list of possible targets, colon-delimited, to reassign to MAKE_TARGET and remove
|
||||||
TEST_TARGET := $$(subst $$(TEST_NAME),,$$(subst $$(TEST_NAME):,,$$(RULE)))
|
TARGETS := :clean:
|
||||||
|
ifneq (,$$(findstring :$$(lastword $$(subst :, ,$$(RULE))):, $$(TARGETS)))
|
||||||
|
MAKE_TARGET := $$(lastword $$(subst :, ,$$(RULE)))
|
||||||
|
TEST_SUBPATH := $$(subst $$(eval) ,/,$$(wordlist 2, $$(words $$(subst :, ,$$(RULE))), _ $$(subst :, ,$$(RULE))))
|
||||||
|
else
|
||||||
|
MAKE_TARGET :=
|
||||||
|
TEST_SUBPATH := $$(subst :,/,$$(RULE))
|
||||||
|
endif
|
||||||
include $(BUILDDEFS_PATH)/testlist.mk
|
include $(BUILDDEFS_PATH)/testlist.mk
|
||||||
ifeq ($$(TEST_NAME),all)
|
ifeq ($$(RULE),all)
|
||||||
MATCHED_TESTS := $$(TEST_LIST)
|
MATCHED_TESTS := $$(TEST_LIST)
|
||||||
else
|
else
|
||||||
MATCHED_TESTS := $$(foreach TEST, $$(TEST_LIST),$$(if $$(findstring x$$(TEST_NAME)x, x$$(notdir $$(TEST))x), $$(TEST),))
|
MATCHED_TESTS := $$(foreach TEST, $$(TEST_LIST),$$(if $$(findstring /$$(TEST_SUBPATH)/, $$(patsubst %,%/,$$(TEST))), $$(TEST),))
|
||||||
endif
|
endif
|
||||||
$$(foreach TEST,$$(MATCHED_TESTS),$$(eval $$(call BUILD_TEST,$$(TEST),$$(TEST_TARGET))))
|
$$(foreach TEST,$$(MATCHED_TESTS),$$(eval $$(call BUILD_TEST,$$(TEST),$$(MAKE_TARGET))))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
$(TEST)_INC := \
|
$(TEST_OUTPUT)_INC := \
|
||||||
tests/test_common/common_config.h
|
tests/test_common/common_config.h
|
||||||
|
|
||||||
$(TEST)_SRC := \
|
$(TEST_OUTPUT)_SRC := \
|
||||||
$(QUANTUM_SRC) \
|
$(QUANTUM_SRC) \
|
||||||
$(SRC) \
|
$(SRC) \
|
||||||
$(QUANTUM_PATH)/keymap_introspection.c \
|
$(QUANTUM_PATH)/keymap_introspection.c \
|
||||||
|
@ -30,8 +30,8 @@ $(TEST)_SRC := \
|
||||||
tests/test_common/test_logger.cpp \
|
tests/test_common/test_logger.cpp \
|
||||||
$(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
|
$(patsubst $(ROOTDIR)/%,%,$(wildcard $(TEST_PATH)/*.cpp))
|
||||||
|
|
||||||
$(TEST)_DEFS := $(OPT_DEFS) "-DKEYMAP_C=\"keymap.c\""
|
$(TEST_OUTPUT)_DEFS := $(OPT_DEFS) "-DKEYMAP_C=\"keymap.c\""
|
||||||
|
|
||||||
$(TEST)_CONFIG := $(TEST_PATH)/config.h
|
$(TEST_OUTPUT)_CONFIG := $(TEST_PATH)/config.h
|
||||||
|
|
||||||
VPATH += $(TOP_DIR)/tests/test_common
|
VPATH += $(TOP_DIR)/tests/test_common
|
||||||
|
|
|
@ -9,13 +9,13 @@ OPT = g
|
||||||
include paths.mk
|
include paths.mk
|
||||||
include $(BUILDDEFS_PATH)/message.mk
|
include $(BUILDDEFS_PATH)/message.mk
|
||||||
|
|
||||||
TARGET=test/$(TEST)
|
TARGET=test/$(TEST_OUTPUT)
|
||||||
|
|
||||||
GTEST_OUTPUT = $(BUILD_DIR)/gtest
|
GTEST_OUTPUT = $(BUILD_DIR)/gtest
|
||||||
|
|
||||||
TEST_OBJ = $(BUILD_DIR)/test_obj
|
TEST_OBJ = $(BUILD_DIR)/test_obj
|
||||||
|
|
||||||
OUTPUTS := $(TEST_OBJ)/$(TEST) $(GTEST_OUTPUT)
|
OUTPUTS := $(TEST_OBJ)/$(TEST_OUTPUT) $(GTEST_OUTPUT)
|
||||||
|
|
||||||
GTEST_INC := \
|
GTEST_INC := \
|
||||||
$(LIB_PATH)/googletest/googletest/include \
|
$(LIB_PATH)/googletest/googletest/include \
|
||||||
|
@ -71,18 +71,18 @@ ifneq ($(filter $(FULL_TESTS),$(TEST)),)
|
||||||
include $(BUILDDEFS_PATH)/build_full_test.mk
|
include $(BUILDDEFS_PATH)/build_full_test.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(TEST)_SRC += \
|
$(TEST_OUTPUT)_SRC += \
|
||||||
tests/test_common/main.cpp \
|
tests/test_common/main.cpp \
|
||||||
$(QUANTUM_PATH)/logging/print.c
|
$(QUANTUM_PATH)/logging/print.c
|
||||||
|
|
||||||
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
|
ifneq ($(strip $(INTROSPECTION_KEYMAP_C)),)
|
||||||
$(TEST)_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
|
$(TEST_OUTPUT)_DEFS += -DINTROSPECTION_KEYMAP_C=\"$(strip $(INTROSPECTION_KEYMAP_C))\"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
$(TEST_OBJ)/$(TEST)_SRC := $($(TEST)_SRC)
|
$(TEST_OBJ)/$(TEST_OUTPUT)_SRC := $($(TEST_OUTPUT)_SRC)
|
||||||
$(TEST_OBJ)/$(TEST)_INC := $($(TEST)_INC) $(VPATH) $(GTEST_INC)
|
$(TEST_OBJ)/$(TEST_OUTPUT)_INC := $($(TEST_OUTPUT)_INC) $(VPATH) $(GTEST_INC)
|
||||||
$(TEST_OBJ)/$(TEST)_DEFS := $($(TEST)_DEFS)
|
$(TEST_OBJ)/$(TEST_OUTPUT)_DEFS := $($(TEST_OUTPUT)_DEFS)
|
||||||
$(TEST_OBJ)/$(TEST)_CONFIG := $($(TEST)_CONFIG)
|
$(TEST_OBJ)/$(TEST_OUTPUT)_CONFIG := $($(TEST_OUTPUT)_CONFIG)
|
||||||
|
|
||||||
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
include $(PLATFORM_PATH)/$(PLATFORM_KEY)/platform.mk
|
||||||
include $(BUILDDEFS_PATH)/common_rules.mk
|
include $(BUILDDEFS_PATH)/common_rules.mk
|
||||||
|
|
|
@ -180,18 +180,18 @@ For more granular control, there is `get_auto_shifted_key`. The default function
|
||||||
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
# ifndef NO_AUTO_SHIFT_ALPHA
|
# ifndef NO_AUTO_SHIFT_ALPHA
|
||||||
case KC_A ... KC_Z:
|
case AUTO_SHIFT_ALPHA:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_NUMERIC
|
# ifndef NO_AUTO_SHIFT_NUMERIC
|
||||||
case KC_1 ... KC_0:
|
case AUTO_SHIFT_NUMERIC:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_SPECIAL
|
# ifndef NO_AUTO_SHIFT_SPECIAL
|
||||||
# ifndef NO_AUTO_SHIFT_TAB
|
# ifndef NO_AUTO_SHIFT_TAB
|
||||||
case KC_TAB:
|
case KC_TAB:
|
||||||
# endif
|
# endif
|
||||||
# ifndef NO_AUTO_SHIFT_SYMBOLS
|
# ifndef NO_AUTO_SHIFT_SYMBOLS
|
||||||
case AUTO_SHIFT_SYMBOLS:
|
case AUTO_SHIFT_SYMBOLS:
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
# ifdef AUTO_SHIFT_ENTER
|
# ifdef AUTO_SHIFT_ENTER
|
||||||
case KC_ENT:
|
case KC_ENT:
|
||||||
|
@ -310,10 +310,16 @@ generating taps on release. For example:
|
||||||
#define RETRO_SHIFT 500
|
#define RETRO_SHIFT 500
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Without a value set, holds of any length without an interrupting key will produce the shifted value.
|
||||||
|
|
||||||
This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
|
This value (if set) must be greater than one's `TAPPING_TERM`, as the key press
|
||||||
must be designated as a 'hold' by `process_tapping` before we send the modifier.
|
must be designated as a 'hold' by `process_tapping` before we send the modifier.
|
||||||
|
[Per-key tapping terms](tap_hold.md#tapping-term) can be used as a workaround.
|
||||||
There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
|
There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys.
|
||||||
|
|
||||||
|
**Note:** Tap Holds must be added to Auto Shift, see [here.](feature_auto_shift.md#auto-shift-per-key)
|
||||||
|
`IS_RETRO` may be helpful if one wants all Tap Holds retro shifted.
|
||||||
|
|
||||||
### Retro Shift and Tap Hold Configurations
|
### Retro Shift and Tap Hold Configurations
|
||||||
|
|
||||||
Tap Hold Configurations work a little differently when using Retro Shift.
|
Tap Hold Configurations work a little differently when using Retro Shift.
|
||||||
|
|
|
@ -36,7 +36,9 @@ Note how there's several different tests, each mocking out a separate part. Also
|
||||||
|
|
||||||
## Running the Tests
|
## Running the Tests
|
||||||
|
|
||||||
To run all the tests in the codebase, type `make test:all`. You can also run test matching a substring by typing `make test:matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer.
|
To run all the tests in the codebase, type `make test:all`. You can also run test matching a substring by typing `make test:matchingsubstring`. `matchingsubstring` can contain colons to be more specific; `make test:tap_hold_configurations` will run the `tap_hold_configurations` tests for all features while `make test:retro_shift:tap_hold_configurations` will run the `tap_hold_configurations` tests for only the Retro Shift feature.
|
||||||
|
|
||||||
|
Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer.
|
||||||
|
|
||||||
## Debugging the Tests
|
## Debugging the Tests
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ void process_action(keyrecord_t *record, action_t action) {
|
||||||
default:
|
default:
|
||||||
if (event.pressed) {
|
if (event.pressed) {
|
||||||
if (tap_count > 0) {
|
if (tap_count > 0) {
|
||||||
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
# ifdef HOLD_ON_OTHER_KEY_PRESS
|
||||||
if (
|
if (
|
||||||
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
||||||
get_hold_on_other_key_press(get_event_keycode(record->event, false), record) &&
|
get_hold_on_other_key_press(get_event_keycode(record->event, false), record) &&
|
||||||
|
|
|
@ -116,25 +116,26 @@ void action_tapping_process(keyrecord_t record) {
|
||||||
* readable. The conditional definition of tapping_keycode and all the
|
* readable. The conditional definition of tapping_keycode and all the
|
||||||
* conditional uses of it are hidden inside macros named TAP_...
|
* conditional uses of it are hidden inside macros named TAP_...
|
||||||
*/
|
*/
|
||||||
# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
|
# define TAP_DEFINE_KEYCODE const uint16_t tapping_keycode = get_record_keycode(&tapping_key, false)
|
||||||
# define TAP_DEFINE_KEYCODE const uint16_t tapping_keycode = get_record_keycode(&tapping_key, false)
|
|
||||||
# else
|
|
||||||
# define TAP_DEFINE_KEYCODE
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
||||||
# ifdef RETRO_TAPPING_PER_KEY
|
# ifdef RETRO_TAPPING_PER_KEY
|
||||||
# define TAP_GET_RETRO_TAPPING get_retro_tapping(tapping_keycode, &tapping_key)
|
# define TAP_GET_RETRO_TAPPING(keyp) get_auto_shifted_key(tapping_keycode, keyp) && get_retro_tapping(tapping_keycode, &tapping_key)
|
||||||
# else
|
# else
|
||||||
# define TAP_GET_RETRO_TAPPING true
|
# define TAP_GET_RETRO_TAPPING(keyp) get_auto_shifted_key(tapping_keycode, keyp)
|
||||||
# endif
|
# endif
|
||||||
# define MAYBE_RETRO_SHIFTING(ev) (TAP_GET_RETRO_TAPPING && (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0))
|
/* Used to extend TAPPING_TERM:
|
||||||
|
* indefinitely if RETRO_SHIFT does not have a value
|
||||||
|
* to RETRO_SHIFT if RETRO_SHIFT is set
|
||||||
|
* for possibly retro shifted keys.
|
||||||
|
*/
|
||||||
|
# define MAYBE_RETRO_SHIFTING(ev, keyp) (get_auto_shifted_key(tapping_keycode, keyp) && TAP_GET_RETRO_TAPPING(keyp) && ((RETRO_SHIFT + 0) == 0 || TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0)))
|
||||||
# define TAP_IS_LT IS_QK_LAYER_TAP(tapping_keycode)
|
# define TAP_IS_LT IS_QK_LAYER_TAP(tapping_keycode)
|
||||||
# define TAP_IS_MT IS_QK_MOD_TAP(tapping_keycode)
|
# define TAP_IS_MT IS_QK_MOD_TAP(tapping_keycode)
|
||||||
# define TAP_IS_RETRO IS_RETRO(tapping_keycode)
|
# define TAP_IS_RETRO IS_RETRO(tapping_keycode)
|
||||||
# else
|
# else
|
||||||
# define TAP_GET_RETRO_TAPPING false
|
# define TAP_GET_RETRO_TAPPING(keyp) false
|
||||||
# define MAYBE_RETRO_SHIFTING(ev) false
|
# define MAYBE_RETRO_SHIFTING(ev, kp) false
|
||||||
# define TAP_IS_LT false
|
# define TAP_IS_LT false
|
||||||
# define TAP_IS_MT false
|
# define TAP_IS_MT false
|
||||||
# define TAP_IS_RETRO false
|
# define TAP_IS_RETRO false
|
||||||
|
@ -187,20 +188,19 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY)
|
||||||
TAP_DEFINE_KEYCODE;
|
TAP_DEFINE_KEYCODE;
|
||||||
|
# endif
|
||||||
|
|
||||||
// process "pressed" tapping key state
|
// process "pressed" tapping key state
|
||||||
if (tapping_key.event.pressed) {
|
if (tapping_key.event.pressed) {
|
||||||
if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) {
|
if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event, keyp)) {
|
||||||
if (IS_NOEVENT(event)) {
|
if (IS_NOEVENT(event)) {
|
||||||
// early return for tick events
|
// early return for tick events
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (tapping_key.tap.count == 0) {
|
if (tapping_key.tap.count == 0) {
|
||||||
if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
|
if (IS_TAPPING_RECORD(keyp) && !event.pressed) {
|
||||||
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
|
||||||
retroshift_swap_times();
|
|
||||||
# endif
|
|
||||||
// first tap!
|
// first tap!
|
||||||
ac_dprintf("Tapping: First tap(0->1).\n");
|
ac_dprintf("Tapping: First tap(0->1).\n");
|
||||||
tapping_key.tap.count = 1;
|
tapping_key.tap.count = 1;
|
||||||
|
@ -218,28 +218,12 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||||
*/
|
*/
|
||||||
// clang-format off
|
// clang-format off
|
||||||
else if (
|
else if (
|
||||||
|
!event.pressed && waiting_buffer_typed(event) &&
|
||||||
(
|
(
|
||||||
!event.pressed && waiting_buffer_typed(event) &&
|
TAP_GET_PERMISSIVE_HOLD ||
|
||||||
TAP_GET_PERMISSIVE_HOLD
|
// Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
|
||||||
)
|
// unnecessarily and fixes them for Layer Taps.
|
||||||
// Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT
|
TAP_GET_RETRO_TAPPING(keyp)
|
||||||
// unnecessarily and fixes them for Layer Taps.
|
|
||||||
|| (TAP_GET_RETRO_TAPPING &&
|
|
||||||
(
|
|
||||||
// Rolled over the two keys.
|
|
||||||
(tapping_key.tap.interrupted == true && (
|
|
||||||
(TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) ||
|
|
||||||
(TAP_IS_MT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
// Makes Retro Shift ignore the default behavior of
|
|
||||||
// MTs and LTs on nested taps below TAPPING_TERM or RETRO_SHIFT
|
|
||||||
|| (
|
|
||||||
TAP_IS_RETRO
|
|
||||||
&& (event.key.col != tapping_key.event.key.col || event.key.row != tapping_key.event.key.row)
|
|
||||||
&& !event.pressed && waiting_buffer_typed(event)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -284,10 +268,16 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||||
process_record(keyp);
|
process_record(keyp);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// set interrupted flag when other key preesed during tapping
|
// set interrupted flag when other key pressed during tapping
|
||||||
if (event.pressed) {
|
if (event.pressed) {
|
||||||
tapping_key.tap.interrupted = true;
|
tapping_key.tap.interrupted = true;
|
||||||
if (TAP_GET_HOLD_ON_OTHER_KEY_PRESS) {
|
if (TAP_GET_HOLD_ON_OTHER_KEY_PRESS
|
||||||
|
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
||||||
|
// Auto Shift cannot evaluate this early
|
||||||
|
// Retro Shift uses the hold action for all nested taps even without HOLD_ON_OTHER_KEY_PRESS, so this is fine to skip
|
||||||
|
&& !(MAYBE_RETRO_SHIFTING(event, keyp) && get_auto_shifted_key(get_record_keycode(keyp, false), keyp))
|
||||||
|
# endif
|
||||||
|
) {
|
||||||
ac_dprintf("Tapping: End. No tap. Interfered by pressed key\n");
|
ac_dprintf("Tapping: End. No tap. Interfered by pressed key\n");
|
||||||
process_record(&tapping_key);
|
process_record(&tapping_key);
|
||||||
tapping_key = (keyrecord_t){0};
|
tapping_key = (keyrecord_t){0};
|
||||||
|
@ -332,6 +322,9 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ac_dprintf("Tapping: key event while last tap(>0).\n");
|
ac_dprintf("Tapping: key event while last tap(>0).\n");
|
||||||
|
# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)
|
||||||
|
retroshift_swap_times();
|
||||||
|
# endif
|
||||||
process_record(keyp);
|
process_record(keyp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -388,7 +381,7 @@ bool process_tapping(keyrecord_t *keyp) {
|
||||||
}
|
}
|
||||||
// process "released" tapping key state
|
// process "released" tapping key state
|
||||||
else {
|
else {
|
||||||
if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) {
|
if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event, keyp)) {
|
||||||
if (IS_NOEVENT(event)) {
|
if (IS_NOEVENT(event)) {
|
||||||
// early return for tick events
|
// early return for tick events
|
||||||
return true;
|
return true;
|
||||||
|
@ -506,9 +499,16 @@ void waiting_buffer_scan_tap(void) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT))
|
||||||
|
TAP_DEFINE_KEYCODE;
|
||||||
|
# endif
|
||||||
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
|
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
|
||||||
keyrecord_t *candidate = &waiting_buffer[i];
|
keyrecord_t *candidate = &waiting_buffer[i];
|
||||||
if (IS_EVENT(candidate->event) && KEYEQ(candidate->event.key, tapping_key.event.key) && !candidate->event.pressed && WITHIN_TAPPING_TERM(candidate->event)) {
|
// clang-format off
|
||||||
|
if (IS_EVENT(candidate->event) && KEYEQ(candidate->event.key, tapping_key.event.key) && !candidate->event.pressed && (
|
||||||
|
WITHIN_TAPPING_TERM(waiting_buffer[i].event) || MAYBE_RETRO_SHIFTING(waiting_buffer[i].event, &tapping_key)
|
||||||
|
)) {
|
||||||
|
// clang-format on
|
||||||
tapping_key.tap.count = 1;
|
tapping_key.tap.count = 1;
|
||||||
candidate->tap.count = 1;
|
candidate->tap.count = 1;
|
||||||
process_record(&tapping_key);
|
process_record(&tapping_key);
|
||||||
|
|
|
@ -66,7 +66,7 @@ __attribute__((weak)) bool get_custom_auto_shifted_key(uint16_t keycode, keyreco
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Called on physical press, returns whether is Auto Shift key */
|
/** \brief Called on physical press, returns whether key is an Auto Shift key */
|
||||||
__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
#ifndef NO_AUTO_SHIFT_ALPHA
|
#ifndef NO_AUTO_SHIFT_ALPHA
|
||||||
|
@ -178,9 +178,8 @@ static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store record to be sent to user functions if there's no release record then.
|
// Store record to be sent to user functions if there's no release record then.
|
||||||
autoshift_lastrecord = *record;
|
autoshift_lastrecord = *record;
|
||||||
autoshift_lastrecord.event.pressed = false;
|
autoshift_lastrecord.event.time = 0;
|
||||||
autoshift_lastrecord.event.time = 0;
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#if defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY)
|
#if defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY)
|
||||||
if (keycode == autoshift_lastkey &&
|
if (keycode == autoshift_lastkey &&
|
||||||
|
@ -409,8 +408,12 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
|
||||||
// If Retro Shift is disabled, possible custom actions shouldn't happen.
|
// If Retro Shift is disabled, possible custom actions shouldn't happen.
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
#if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING)
|
||||||
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
# ifdef HOLD_ON_OTHER_KEY_PRESS
|
||||||
const bool is_hold_on_interrupt = get_hold_on_other_key_press(keycode, record);
|
const bool is_hold_on_interrupt = (IS_QK_MOD_TAP(keycode)
|
||||||
|
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
||||||
|
&& get_hold_on_other_key_press(keycode, record)
|
||||||
|
# endif
|
||||||
|
);
|
||||||
# else
|
# else
|
||||||
const bool is_hold_on_interrupt = false;
|
const bool is_hold_on_interrupt = false;
|
||||||
# endif
|
# endif
|
||||||
|
@ -450,8 +453,12 @@ bool process_auto_shift(uint16_t keycode, keyrecord_t *record) {
|
||||||
#endif
|
#endif
|
||||||
) {
|
) {
|
||||||
// Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set.
|
// Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set.
|
||||||
#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
#ifdef HOLD_ON_OTHER_KEY_PRESS
|
||||||
if (autoshift_flags.in_progress && get_hold_on_other_key_press(keycode, record)) {
|
if (autoshift_flags.in_progress
|
||||||
|
# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY
|
||||||
|
&& get_hold_on_other_key_press(keycode, record)
|
||||||
|
# endif
|
||||||
|
) {
|
||||||
autoshift_end(KC_NO, now, false, &autoshift_lastrecord);
|
autoshift_end(KC_NO, now, false, &autoshift_lastrecord);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -488,10 +495,8 @@ void retroshift_poll_time(keyevent_t *event) {
|
||||||
}
|
}
|
||||||
// Used to swap the times of Retro Shifted key and Auto Shift key that interrupted it.
|
// Used to swap the times of Retro Shifted key and Auto Shift key that interrupted it.
|
||||||
void retroshift_swap_times(void) {
|
void retroshift_swap_times(void) {
|
||||||
if (last_retroshift_time != 0 && autoshift_flags.in_progress) {
|
if (autoshift_flags.in_progress) {
|
||||||
uint16_t temp = retroshift_time;
|
autoshift_time = last_retroshift_time;
|
||||||
retroshift_time = last_retroshift_time;
|
|
||||||
last_retroshift_time = temp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,4 +56,5 @@ uint16_t (get_autoshift_timeout)(uint16_t keycode, keyrecord_t *record);
|
||||||
void set_autoshift_timeout(uint16_t timeout);
|
void set_autoshift_timeout(uint16_t timeout);
|
||||||
void autoshift_matrix_scan(void);
|
void autoshift_matrix_scan(void);
|
||||||
bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
|
bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define AUTO_SHIFT_REPEAT
|
||||||
|
#define AUTO_SHIFT_NO_AUTO_REPEAT
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class AutoShiftNoAutoRepeat : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(AutoShiftNoAutoRepeat, no_auto_repeat) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto repeat_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({repeat_key});
|
||||||
|
|
||||||
|
/* Press repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Idle for auto-repeat to (not) kick in. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AutoShiftNoAutoRepeat, tap_regular_key_while_another_key_repeats) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto repeat_key = KeymapKey(0, 1, 0, KC_P);
|
||||||
|
auto regular_key = KeymapKey(0, 2, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({repeat_key, regular_key});
|
||||||
|
|
||||||
|
/* Press repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release repeat key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
repeat_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press repeat key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
repeat_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release repeat key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
repeat_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define AUTO_SHIFT_REPEAT
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,107 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class AutoShiftRepeat : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(AutoShiftRepeat, tap_regular_key_cancelling_another_key_hold) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto repeat_key = KeymapKey(0, 1, 0, KC_P);
|
||||||
|
auto regular_key = KeymapKey(0, 2, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({repeat_key, regular_key});
|
||||||
|
|
||||||
|
/* Press repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(testing::AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(testing::AnyNumber());
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(testing::AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(testing::AnyNumber());
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AutoShiftRepeat, tap_regular_key_while_another_key_is_held) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto repeat_key = KeymapKey(0, 1, 0, KC_P);
|
||||||
|
auto regular_key = KeymapKey(0, 2, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({repeat_key, regular_key});
|
||||||
|
|
||||||
|
/* Press repeat key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
repeat_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Idle for auto-repeat to kick in. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_P));
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release repeat key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
repeat_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define RETRO_SHIFT 2 * TAPPING_TERM
|
||||||
|
// releases between AUTO_SHIFT_TIMEOUT and TAPPING_TERM are not tested
|
||||||
|
#define AUTO_SHIFT_TIMEOUT TAPPING_TERM
|
||||||
|
#define AUTO_SHIFT_MODIFIERS
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* Copyright 2021 Stefan Kerkmann
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define RETRO_SHIFT
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class RetroShiftDefaultTapHold : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, hold_mod_tap_key_for_long) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(4 * TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,485 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class RetroShiftDefaultTapHold : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, tap_mod_tap_key) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, hold_mod_tap_key_under_retro_shift) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, hold_mod_tap_key_over_retro_shift) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(RETRO_SHIFT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, tap_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, tap_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, hold_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, hold_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, roll_tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, roll_tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, roll_hold_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftDefaultTapHold, roll_hold_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define HOLD_ON_OTHER_KEY_PRESS
|
||||||
|
|
||||||
|
#define RETRO_SHIFT 2 * TAPPING_TERM
|
||||||
|
// releases between AUTO_SHIFT_TIMEOUT and TAPPING_TERM are not tested
|
||||||
|
#define AUTO_SHIFT_TIMEOUT TAPPING_TERM
|
||||||
|
#define AUTO_SHIFT_MODIFIERS
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,442 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class RetroShiftHoldOnOtherKeyPress : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, tap_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, tap_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, hold_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, hold_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, roll_tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, roll_tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, roll_hold_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftHoldOnOtherKeyPress, roll_hold_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define PERMISSIVE_HOLD
|
||||||
|
|
||||||
|
#define RETRO_SHIFT 2 * TAPPING_TERM
|
||||||
|
// releases between AUTO_SHIFT_TIMEOUT and TAPPING_TERM are not tested
|
||||||
|
#define AUTO_SHIFT_TIMEOUT TAPPING_TERM
|
||||||
|
#define AUTO_SHIFT_MODIFIERS
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,419 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class RetroShiftPermissiveHold : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, tap_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, tap_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, hold_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, hold_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, roll_tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, roll_tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, roll_hold_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHold, roll_hold_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_REPORT(driver, (KC_P));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))).Times(AnyNumber());
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define HOLD_ON_OTHER_KEY_PRESS
|
||||||
|
#define PERMISSIVE_HOLD
|
||||||
|
|
||||||
|
#define RETRO_SHIFT 2 * TAPPING_TERM
|
||||||
|
// releases between AUTO_SHIFT_TIMEOUT and TAPPING_TERM are not tested
|
||||||
|
#define AUTO_SHIFT_TIMEOUT TAPPING_TERM
|
||||||
|
#define AUTO_SHIFT_MODIFIERS
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Copyright 2022 Isaac Elenbaas
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
# Keep this file, even if it is empty, as a marker that this folder contains tests
|
||||||
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
|
@ -0,0 +1,442 @@
|
||||||
|
/* Copyright 2022 Isaac Elenbaas
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "action_tapping.h"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
using testing::_;
|
||||||
|
using testing::AnyNumber;
|
||||||
|
using testing::AnyOf;
|
||||||
|
using testing::InSequence;
|
||||||
|
|
||||||
|
class RetroShiftPermissiveHoldHoldOnOtherKeyPress : public TestFixture {};
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, tap_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, tap_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, hold_regular_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, hold_mod_tap_key_while_mod_tap_key_is_held_over_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
idle_for(TAPPING_TERM);
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, roll_tap_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, roll_tap_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL));
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, roll_hold_regular_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto regular_key = KeymapKey(0, 1, 0, KC_A);
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(RetroShiftPermissiveHoldHoldOnOtherKeyPress, roll_hold_mod_tap_key_while_mod_tap_key_is_held_under_tapping_term) {
|
||||||
|
TestDriver driver;
|
||||||
|
InSequence s;
|
||||||
|
auto mod_tap_hold_key = KeymapKey(0, 0, 0, CTL_T(KC_P));
|
||||||
|
auto mod_tap_regular_key = KeymapKey(0, 1, 0, ALT_T(KC_A));
|
||||||
|
|
||||||
|
set_keymap({mod_tap_hold_key, mod_tap_regular_key});
|
||||||
|
|
||||||
|
/* Press mod-tap-hold key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_hold_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Press mod-tap-regular key. */
|
||||||
|
EXPECT_NO_REPORT(driver);
|
||||||
|
mod_tap_regular_key.press();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-hold key. */
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LCTL))).Times(AnyNumber());
|
||||||
|
mod_tap_hold_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
|
||||||
|
/* Release mod-tap-regular key. */
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_REPORT(driver, (KC_LCTL, KC_LSFT, KC_A));
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(KC_LCTL, KC_LSFT),
|
||||||
|
KeyboardReport(KC_LSFT),
|
||||||
|
KeyboardReport(KC_LCTL))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
EXPECT_EMPTY_REPORT(driver);
|
||||||
|
idle_for(AUTO_SHIFT_TIMEOUT);
|
||||||
|
mod_tap_regular_key.release();
|
||||||
|
run_one_scan_loop();
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2022 Google LLC
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "test_common.h"
|
||||||
|
|
||||||
|
#define TAPPING_TERM 200
|
||||||
|
#define AUTO_SHIFT_TIMEOUT 150
|
|
@ -27,6 +27,10 @@
|
||||||
KeyboardReport(KC_LSFT))))
|
KeyboardReport(KC_LSFT))))
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
using ::testing::_;
|
using ::testing::_;
|
||||||
using ::testing::AnyNumber;
|
using ::testing::AnyNumber;
|
||||||
using ::testing::AnyOf;
|
using ::testing::AnyOf;
|
|
@ -0,0 +1,18 @@
|
||||||
|
# Copyright 2022 Google LLC
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
CAPS_WORD_ENABLE = yes
|
||||||
|
AUTO_SHIFT_ENABLE = yes
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright 2022 Google LLC
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 2 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "keyboard_report_util.hpp"
|
||||||
|
#include "keycode.h"
|
||||||
|
#include "test_common.hpp"
|
||||||
|
#include "test_fixture.hpp"
|
||||||
|
#include "test_keymap_key.hpp"
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::AnyNumber;
|
||||||
|
using ::testing::AnyOf;
|
||||||
|
using ::testing::InSequence;
|
||||||
|
|
||||||
|
class CapsWord : public TestFixture {
|
||||||
|
public:
|
||||||
|
void SetUp() override {
|
||||||
|
caps_word_off();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Tests that with Auto Shift, letter keys are shifted by Caps Word
|
||||||
|
// regardless of whether they are released before AUTO_SHIFT_TIMEOUT.
|
||||||
|
TEST_F(CapsWord, AutoShiftKeys) {
|
||||||
|
TestDriver driver;
|
||||||
|
KeymapKey key_a(0, 0, 0, KC_A);
|
||||||
|
KeymapKey key_spc(0, 1, 0, KC_SPC);
|
||||||
|
set_keymap({key_a, key_spc});
|
||||||
|
|
||||||
|
// Allow any number of reports with no keys or only KC_LSFT.
|
||||||
|
// clang-format off
|
||||||
|
EXPECT_CALL(driver, send_keyboard_mock(AnyOf(
|
||||||
|
KeyboardReport(),
|
||||||
|
KeyboardReport(KC_LSFT))))
|
||||||
|
.Times(AnyNumber());
|
||||||
|
// clang-format on
|
||||||
|
{ // Expect: "A, A, space, a".
|
||||||
|
InSequence s;
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_LSFT, KC_A));
|
||||||
|
EXPECT_REPORT(driver, (KC_SPC));
|
||||||
|
EXPECT_REPORT(driver, (KC_A));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn on Caps Word and type "A (quick tap), A (long press), space, A".
|
||||||
|
caps_word_on();
|
||||||
|
|
||||||
|
tap_key(key_a); // Tap A quickly.
|
||||||
|
tap_key(key_a, AUTO_SHIFT_TIMEOUT + 1); // Long press A.
|
||||||
|
tap_key(key_spc);
|
||||||
|
tap_key(key_a);
|
||||||
|
|
||||||
|
testing::Mock::VerifyAndClearExpectations(&driver);
|
||||||
|
}
|
Loading…
Reference in New Issue