diff options
author | Stefan Kerkmann <karlk90@pm.me> | 2021-11-23 03:31:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-23 13:31:01 +1100 |
commit | a24bdccee0580d1263733bc7e66e4e4f97713f19 (patch) | |
tree | 868cb12a436a87b39c936292f442bcc266ae0224 /tests | |
parent | e20bc76a1e05d02c15a452e51fa76d9ec39b0369 (diff) |
[Tests] Increase QMK test coverage take 2 (#15269)
* Add per-test keymaps
* Add better trace and info logs for failed unit-tests
* Add layer state assertion with tracing message
* Use individual test binaries configuration options
* Add basic qmk functionality tests
* Add tap hold configurations tests
* Add auto shift tests
Co-authored-by: Nick Brassel <nick@tzarc.org>
Diffstat (limited to 'tests')
44 files changed, 2674 insertions, 222 deletions
diff --git a/tests/auto_shift/config.h b/tests/auto_shift/config.h new file mode 100644 index 0000000000..4f343b4529 --- /dev/null +++ b/tests/auto_shift/config.h @@ -0,0 +1,19 @@ +/* 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"
\ No newline at end of file diff --git a/tests/auto_shift/test.mk b/tests/auto_shift/test.mk new file mode 100644 index 0000000000..4259c606e4 --- /dev/null +++ b/tests/auto_shift/test.mk @@ -0,0 +1,20 @@ +# 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/>. + +# -------------------------------------------------------------------------------- +# Keep this file, even if it is empty, as a marker that this folder contains tests +# -------------------------------------------------------------------------------- + +AUTO_SHIFT_ENABLE = yes
\ No newline at end of file diff --git a/tests/auto_shift/test_auto_shift.cpp b/tests/auto_shift/test_auto_shift.cpp new file mode 100644 index 0000000000..9c5ed9a832 --- /dev/null +++ b/tests/auto_shift/test_auto_shift.cpp @@ -0,0 +1,73 @@ +/* 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/>. + */ + +#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::InSequence; + +class AutoShift : public TestFixture {}; + +TEST_F(AutoShift, key_release_before_timeout) { + TestDriver driver; + InSequence s; + auto regular_key = KeymapKey(0, 2, 0, KC_A); + + set_keymap({regular_key}); + + /* Press regular key */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + regular_key.press(); + run_one_scan_loop(); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release regular key */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_A))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())); + regular_key.release(); + run_one_scan_loop(); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(AutoShift, key_release_after_timeout) { + TestDriver driver; + InSequence s; + auto regular_key = KeymapKey(0, 2, 0, KC_A); + + set_keymap({regular_key}); + + /* Press regular key */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + regular_key.press(); + idle_for(AUTO_SHIFT_TIMEOUT); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release regular key */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT, KC_A))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_LSFT))); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())); + regular_key.release(); + run_one_scan_loop(); + testing::Mock::VerifyAndClearExpectations(&driver); +}
\ No newline at end of file diff --git a/tests/basic/config.h b/tests/basic/config.h index 99bd62d991..85fa9d691d 100644 --- a/tests/basic/config.h +++ b/tests/basic/config.h @@ -16,5 +16,4 @@ #pragma once -#define MATRIX_ROWS 4 -#define MATRIX_COLS 10 +#include "test_common.h"
\ No newline at end of file diff --git a/tests/basic/keymap.c b/tests/basic/keymap.c deleted file mode 100644 index 2b5747abb7..0000000000 --- a/tests/basic/keymap.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2017 Fred Sundvik - * - * 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 "quantum.h" - -// Don't rearrange keys as existing tests might rely on the order -// Col2, Row 0 has to be KC_NO, because tests rely on it - -#define COMBO1 RSFT(LCTL(KC_O)) - -const uint16_t PROGMEM - keymaps[][MATRIX_ROWS][MATRIX_COLS] = - { - [0] = - { - // 0 1 2 3 4 5 6 7 8 9 - {KC_A, KC_B, KC_NO, KC_LSFT, KC_RSFT, KC_LCTL, COMBO1, SFT_T(KC_P), M(0), KC_NO}, - {KC_EQL, KC_PLUS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}, - {KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}, - {KC_C, KC_D, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO}, - }, -}; - -const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { - if (record->event.pressed) { - switch (id) { - case 0: - return MACRO(D(LSFT), T(H), U(LSFT), T(E), T(L), T(L), T(O), T(SPACE), W(100), D(LSFT), T(W), U(LSFT), I(10), T(O), T(R), T(L), T(D), D(LSFT), T(1), U(LSFT), END); - } - } - return MACRO_NONE; -}; diff --git a/tests/basic/test.mk b/tests/basic/test.mk new file mode 100644 index 0000000000..29690d1adf --- /dev/null +++ b/tests/basic/test.mk @@ -0,0 +1,18 @@ +# Copyright 2017 Fred Sundvik +# +# 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 +# --------------------------------------------------------------------------------
\ No newline at end of file diff --git a/tests/basic/test_action_layer.cpp b/tests/basic/test_action_layer.cpp index d00a0859b9..1b12d13642 100644 --- a/tests/basic/test_action_layer.cpp +++ b/tests/basic/test_action_layer.cpp @@ -14,39 +14,54 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "gtest/gtest.h" +#include "keyboard_report_util.hpp" #include "test_common.hpp" using testing::_; -using testing::Return; +using testing::InSequence; class ActionLayer : public TestFixture {}; -// TEST_F(ActionLayer, LayerStateDBG) { -// layer_state_set(0); -// } - -// TEST_F(ActionLayer, LayerStateSet) { -// layer_state_set(0); -// EXPECT_EQ(layer_state, 0); -// layer_state_set(0b001100); -// EXPECT_EQ(layer_state, 0b001100); -// } - -// TEST_F(ActionLayer, LayerStateIs) { -// layer_state_set(0); -// EXPECT_EQ(layer_state_is(0), true); -// EXPECT_EQ(layer_state_is(1), true); -// layer_state_set(1); -// EXPECT_EQ(layer_state_is(0), true); -// EXPECT_EQ(layer_state_is(1), true); -// layer_state_set(2); -// EXPECT_EQ(layer_state_is(0), false); -// EXPECT_EQ(layer_state_is(1), false); -// EXPECT_EQ(layer_state_is(2), true); -// } +TEST_F(ActionLayer, LayerStateDBG) { + TestDriver driver; + + layer_state_set(0); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerStateSet) { + TestDriver driver; + + layer_state_set(0); + EXPECT_EQ(layer_state, 0); + layer_state_set(0b001100); + EXPECT_EQ(layer_state, 0b001100); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerStateIs) { + TestDriver driver; + + layer_state_set(0); + EXPECT_EQ(layer_state_is(0), true); + EXPECT_EQ(layer_state_is(1), false); + layer_state_set(1); + EXPECT_EQ(layer_state_is(0), true); + EXPECT_EQ(layer_state_is(1), false); + layer_state_set(2); + EXPECT_EQ(layer_state_is(0), false); + EXPECT_EQ(layer_state_is(1), true); + EXPECT_EQ(layer_state_is(2), false); + + testing::Mock::VerifyAndClearExpectations(&driver); +} TEST_F(ActionLayer, LayerStateCmp) { - uint32_t prev_layer; + TestDriver driver; + uint32_t prev_layer; prev_layer = 0; EXPECT_EQ(layer_state_cmp(prev_layer, 0), true); @@ -60,33 +75,339 @@ TEST_F(ActionLayer, LayerStateCmp) { EXPECT_EQ(layer_state_cmp(prev_layer, 0), false); EXPECT_EQ(layer_state_cmp(prev_layer, 1), true); EXPECT_EQ(layer_state_cmp(prev_layer, 2), false); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerClear) { + TestDriver driver; + + layer_clear(); + EXPECT_EQ(layer_state, 0); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerMove) { + TestDriver driver; + + layer_move(0); + EXPECT_EQ(layer_state, 1); + layer_move(3); + EXPECT_EQ(layer_state, 0b1000); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerOn) { + TestDriver driver; + + layer_clear(); + layer_on(1); + layer_on(3); + layer_on(3); + EXPECT_EQ(layer_state, 0b1010); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerOff) { + TestDriver driver; + + layer_clear(); + layer_on(1); + layer_on(3); + layer_off(3); + layer_off(2); + EXPECT_EQ(layer_state, 0b0010); + + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, MomentaryLayerDoesNothing) { + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, MO(1)}; + + set_keymap({layer_key}); + + /* Press and release MO, nothing should happen. */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.press(); + run_one_scan_loop(); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.release(); + run_one_scan_loop(); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, MomentaryLayerWithKeypress) { + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, MO(1)}; + + /* These keys must have the same position in the matrix, only the layer is different. */ + KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A}; + set_keymap({layer_key, regular_key, KeymapKey{1, 1, 0, KC_B}}); + + /* Press MO. */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Press key on layer 1 */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_B))).Times(1); + regular_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release key on layer 1 */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + regular_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release MO */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, ToggleLayerDoesNothing) { + GTEST_SKIP() << "TODO: Toggle layer does not activate the expected layer on key press but on release."; + + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, TG(1)}; + + set_keymap({layer_key}); + + /* Press TG. Layer state should not change as it's applied on release. */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release TG. */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, ToggleLayerUpAndDown) { + GTEST_SKIP() << "TODO: Toggle layer does not activate the expected layer on key press but on release."; + + TestDriver driver; + KeymapKey toggle_layer_1_on_layer_0 = KeymapKey{0, 0, 0, TG(1)}; + KeymapKey toggle_layer_0_on_layer_1 = KeymapKey{1, 1, 0, TG(0)}; + + set_keymap({toggle_layer_1_on_layer_0, toggle_layer_0_on_layer_1}); + + /* Toggle Layer 1. */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + toggle_layer_1_on_layer_0.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + toggle_layer_1_on_layer_0.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Toggle Layer 0. */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + toggle_layer_0_on_layer_1.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + toggle_layer_0_on_layer_1.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerTapToggleDoesNothing) { + GTEST_SKIP() << "TODO: Tap toggle layer does not activate the expected layer on key press."; + + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, TT(1)}; + + set_keymap({layer_key}); + + /* Press and release TT. */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(0); + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(2); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerTapToggleWithKeypress) { + GTEST_SKIP() << "TODO: Tap toggle layer does not activate the expected layer on key press."; + + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, TT(1)}; + + /* These keys must have the same position in the matrix, only the layer is different. */ + KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A}; + set_keymap({layer_key, regular_key, KeymapKey{1, 1, 0, KC_B}}); + + /* Press TT. */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(0); + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_B))).Times(1); + regular_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + regular_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); +} + +TEST_F(ActionLayer, LayerTapToggleWithToggleWithKeypress) { + GTEST_SKIP() << "TODO: Tap toggle layer does not activate the expected layer on key press."; + + TestDriver driver; + KeymapKey layer_key = KeymapKey{0, 0, 0, TT(1)}; + + /* These keys must have the same position in the matrix, only the layer is different. */ + KeymapKey regular_key = KeymapKey{0, 1, 0, KC_A}; + set_keymap({layer_key, regular_key, KeymapKey{1, 1, 0, KC_B}}); + + /* Tap TT five times . */ + /* TODO: QMK currently sends an empty report even if nothing needs to be reported to the host! */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(9); + + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + + layer_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + layer_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + + testing::Mock::VerifyAndClearExpectations(&driver); + + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_B))).Times(1); + regular_key.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(1); + regular_key.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); } -// TEST_F(ActionLayer, LayerClear) { -// layer_clear(); -// EXPECT_EQ(layer_state, 0); -// } - -// TEST_F(ActionLayer, LayerMove) { -// layer_move(0); -// EXPECT_EQ(layer_state, 1); -// layer_move(3); -// EXPECT_EQ(layer_state, 0b1000); -// } - -// TEST_F(ActionLayer, LayerOn) { -// layer_clear(); -// layer_on(1); -// layer_on(3); -// layer_on(3); -// EXPECT_EQ(layer_state, 0b1010); -// } - -// TEST_F(ActionLayer, LayerOff) { -// layer_clear(); -// layer_on(1); -// layer_on(3); -// layer_off(3); -// layer_off(2); -// EXPECT_EQ(layer_state, 0b1000); -// } +TEST_F(ActionLayer, LayerTapReleasedBeforeKeypressReleaseWithModifiers) { + GTEST_SKIP() << "TODO: Modifiers are erroneously discarded on layer changes, although a key that introduced the modifier is still held."; + TestDriver driver; + InSequence s; + + KeymapKey layer_0_key_0 = KeymapKey{0, 0, 0, LT(1, KC_T)}; + KeymapKey layer_1_key_1 = KeymapKey{1, 1, 0, RALT(KC_9)}; + + set_keymap({layer_0_key_0, layer_1_key_1}); + + /* Press layer tap and wait for tapping term to switch to layer 1 */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport())).Times(0); + layer_0_key_0.press(); + idle_for(TAPPING_TERM); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Press key with layer 1 mapping, result basically expected + * altough more reports are send then necessary. */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RALT))).Times(1); + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RALT, KC_9))).Times(1); + layer_1_key_1.press(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(1)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Release layer tap key, no report is send because key is still held. */ + EXPECT_CALL(driver, send_keyboard_mock(_)).Times(0); + layer_0_key_0.release(); + run_one_scan_loop(); + EXPECT_TRUE(layer_state_is(0)); + testing::Mock::VerifyAndClearExpectations(&driver); + + /* Unregister keycode and modifier. */ + EXPECT_CALL(driver, send_keyboard_mock(KeyboardReport(KC_RALT))).Times(1) |