diff --git a/tests/features/layers/activation-order/sketch.ino b/tests/features/layers/activation-order/sketch.ino index cf592980..60f39a09 100644 --- a/tests/features/layers/activation-order/sketch.ino +++ b/tests/features/layers/activation-order/sketch.ino @@ -23,52 +23,52 @@ KEYMAPS( [0] = KEYMAP_STACKED ( - Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,M(0) + Key_0 ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,M(0) ,ShiftToLayer(1) - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A ,Key_A - ,Key_A ,Key_A ,Key_A ,Key_A + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,Key_0 + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,ShiftToLayer(2) ), [1] = KEYMAP_STACKED ( - Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B + Key_1 ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,___ - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B ,Key_B - ,Key_B ,Key_B ,Key_B ,Key_B + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,Key_1 + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,___ ), [2] = KEYMAP_STACKED ( - Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C + Key_2 ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,___ - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C ,Key_C - ,Key_C ,Key_C ,Key_C ,Key_C + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,Key_2 + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX ,XXX + ,XXX ,XXX ,XXX ,XXX ,___ ) ) // KEYMAPS( diff --git a/tests/features/layers/activation-order/test/testcase.cpp b/tests/features/layers/activation-order/test/testcase.cpp index 31ab26c1..320dc3d6 100644 --- a/tests/features/layers/activation-order/test/testcase.cpp +++ b/tests/features/layers/activation-order/test/testcase.cpp @@ -26,150 +26,179 @@ using ::testing::IsEmpty; class LayerActivationOrder : public VirtualDeviceTest { public: - void SingleKeyTest(Key k) { - sim_.Press(0, 0); // k - auto state = RunCycle(); + const KeyAddr KEYSWITCH_TOP_LEFT = KeyAddr{0, 0}; // layer-dependent key + const KeyAddr KEYSWITCH_TOP_RIGHT = KeyAddr{0, 15}; // layer-dependent key + const KeyAddr KEYSWITCH_LEFT_PALM = KeyAddr{3, 6}; // ShiftToLayer(1) + const KeyAddr KEYSWITCH_RIGHT_PALM = KeyAddr{3, 9}; // ShiftToLayer(2) + const KeyAddr KEYSWITCH_LEFT_THUMB_RIGHTMOST = KeyAddr{3, 7}; // L0 deactivate macro + + const Key LAYER0_KEY = Key_0; + const Key LAYER1_KEY = Key_1; + const Key LAYER2_KEY = Key_2; + + void pressKeyswitch(const KeyAddr& addr) { + sim_.Press(addr.row(), addr.col()); + } + + void releaseKeyswitch(const KeyAddr& addr) { + sim_.Release(addr.row(), addr.col()); + } + + auto pressKeyswitchAndCycle(const KeyAddr& addr) { + pressKeyswitch(addr); + return RunCycle(); + } + + auto releaseKeyswitchAndCycle(const KeyAddr& addr) { + releaseKeyswitch(addr); + return RunCycle(); + } + void assertSingleReportThatContains(std::unique_ptr &state, Key k) { ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); EXPECT_THAT( state->HIDReports()->Keyboard(0).ActiveKeycodes(), Contains(k)); + } - sim_.Release(0, 0); // k - state = RunCycle(); + void assertSingleReportThatDoesNotContain(std::unique_ptr &state, Key k) { + ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); + EXPECT_THAT( + state->HIDReports()->Keyboard(0).ActiveKeycodes(), + ::testing::Not(Contains(k))); + } + void assertSingleEmptyReport(std::unique_ptr &state) { ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); EXPECT_THAT( state->HIDReports()->Keyboard(0).ActiveKeycodes(), IsEmpty()); + } + + void assertNoReport(std::unique_ptr &state) { + ASSERT_EQ(state->HIDReports()->Keyboard().size(), 0); + } + + void assertNoReportAfterCycle() { + auto state = RunCycle(); + assertNoReport(state); + } + + void TestPressAndRelease(const KeyAddr& addr, Key k) { + auto state = pressKeyswitchAndCycle(addr); + assertSingleReportThatContains(state, k); - state = RunCycle(); + state = releaseKeyswitchAndCycle(addr); + assertSingleEmptyReport(state); - // 2 cycles after releasing k - EXPECT_EQ(state->HIDReports()->Keyboard().size(), 0); + assertNoReportAfterCycle(); } }; TEST_F(LayerActivationOrder, BaseLayerHasNotRegressed) { - SingleKeyTest(Key_A); + TestPressAndRelease(KEYSWITCH_TOP_LEFT, LAYER0_KEY); } TEST_F(LayerActivationOrder, ShifToLayerOne) { - // Pressing (3,6) shifts to Layer 1, and we stay there until release. + // Pressing (KEYSWITCH_LEFT_PALM) shifts to Layer 1, and we stay there until release. + auto state = pressKeyswitchAndCycle(KEYSWITCH_LEFT_PALM); + TestPressAndRelease(KEYSWITCH_TOP_LEFT, LAYER1_KEY); - sim_.Press(3, 6); // ShiftToLayer(1) - auto state = RunCycle(); - - SingleKeyTest(Key_B); - - // Releasing (3,6) gets us back to the base layer - sim_.Release(3, 6); // ShiftToLayer(1) - state = RunCycle(); - - SingleKeyTest(Key_A); + // Releasing (KEYSWITCH_LEFT_PALM) gets us back to the base layer + state = releaseKeyswitchAndCycle(KEYSWITCH_LEFT_PALM); + TestPressAndRelease(KEYSWITCH_TOP_LEFT, LAYER0_KEY); } TEST_F(LayerActivationOrder, ShiftingWithCaching) { - // Pressing (0, 0) will activate A - sim_.Press(0, 0); - auto state = RunCycle(); - - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_A)); + // Pressing (KEYSWITCH_TOP_LEFT) will activate the key on layer 0 + auto state = pressKeyswitchAndCycle(KEYSWITCH_TOP_LEFT); + assertSingleReportThatContains(state, LAYER0_KEY); - // Pressing (3, 6) will switch to Layer 1 - sim_.Press(3, 6); - state = RunCycle(); - - // ...since we're still pressing (0, 0), and there was no change in the HID - // states, we shouldn't emit a report. - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 0); + // Pressing (KEYSWITCH_LEFT_PALM) will switch to Layer 1 + state = pressKeyswitchAndCycle(KEYSWITCH_LEFT_PALM); - // Pressing (0, 1), the report shall contain 'A' _and_ 'B'. - sim_.Press(0, 1); - state = RunCycle(); + // ...since we're still pressing (KEYSWITCH_TOP_LEFT), and there was no change + // in the HID states, we shouldn't emit a report. + assertNoReport(state); - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_A)); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_B)); - - // Releasing (0, 0), the report should now contain B only - sim_.Release(0, 0); - state = RunCycle(); + // Pressing (KEYSWITCH_TOP_RIGHT), the report shall contain keys from both + // layer 0 and layer1, because we started holding the layer 0 key prior to + // switching layers, so it's code should remain cached. + state = pressKeyswitchAndCycle(KEYSWITCH_TOP_RIGHT); + assertSingleReportThatContains(state, LAYER0_KEY); + assertSingleReportThatContains(state, LAYER1_KEY); - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_B)); + // Releasing (KEYSWITCH_TOP_LEFT), the report should now contain the key from + // layer1 only, and should not contain the layer0 key anymore. + state = releaseKeyswitchAndCycle(KEYSWITCH_TOP_LEFT); + assertSingleReportThatContains(state, LAYER1_KEY); + assertSingleReportThatDoesNotContain(state, LAYER0_KEY); - // Release (0, 1) - sim_.Release(0, 1); - state = RunCycle(); + // Release (KEYSWITCH_TOP_RIGHT) + state = releaseKeyswitchAndCycle(KEYSWITCH_TOP_RIGHT); - // Test B in isolation again - SingleKeyTest(Key_B); + // Test the layer 1 key in isolation again + TestPressAndRelease(KEYSWITCH_TOP_LEFT, LAYER1_KEY); // Release the layer key as well. - sim_.Release(3, 6); - state = RunCycle(); + state = releaseKeyswitchAndCycle(KEYSWITCH_LEFT_PALM); - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 0); + // Since the layer key release is internal to us, we shouldn't send a report. + assertNoReport(state); } TEST_F(LayerActivationOrder, Ordering) { - // Pressing (3, 9) will switch to Layer 2 - sim_.Press(3, 9); - auto state = RunCycle(); - - // Pressing (0, 0) will activate 'C' - sim_.Press(0, 0); - state = RunCycle(); - - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_C)); - - // Pressing (3, 6) will activate Layer 1 - sim_.Press(3, 6); + // Pressing (KEYSWITCH_RIGHT_PALM) will switch to Layer 2 + auto state = pressKeyswitchAndCycle(KEYSWITCH_RIGHT_PALM); + + // Pressing (KEYSWITCH_TOP_LEFT) will activate a key on layer 2 + state = pressKeyswitchAndCycle(KEYSWITCH_TOP_LEFT); + assertSingleReportThatContains(state, LAYER2_KEY); + + // Pressing (KEYSWITCH_LEFT_PALM) will activate Layer 1 + state = pressKeyswitchAndCycle(KEYSWITCH_LEFT_PALM); + + // Pressing (KEYSWITCH_TOP_RIGHT) will activate the layer 1 key now, due to + // activation ordering. + state = pressKeyswitchAndCycle(KEYSWITCH_TOP_RIGHT); + + // We should have both the layer 1 and the layer 2 key active, because we're + // holding both. + assertSingleReportThatContains(state, LAYER1_KEY); + assertSingleReportThatContains(state, LAYER2_KEY); + + // Releaseing all held keys, we should get an empty report. + releaseKeyswitch(KEYSWITCH_TOP_LEFT); + releaseKeyswitch(KEYSWITCH_TOP_RIGHT); + releaseKeyswitch(KEYSWITCH_LEFT_PALM); + releaseKeyswitch(KEYSWITCH_RIGHT_PALM); state = RunCycle(); - // Pressing (0, 1) will activate 'B' now, due to activation ordering. - sim_.Press(0, 1); - state = RunCycle(); + assertSingleEmptyReport(state); - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_C)); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_B)); - - sim_.Release(0, 0); - sim_.Release(0, 1); - sim_.Release(3, 6); - sim_.Release(3, 9); + // One more cycle, and we should generate no report at all state = RunCycle(); + assertNoReport(state); } TEST_F(LayerActivationOrder, LayerZero) { - sim_.Press(3, 7); // Macro#0: Layer.deactivate(0) - auto state = RunCycle(); + // Pressing the rightmost of the left thumb keys should deactivate layer 0 + auto state = pressKeyswitchAndCycle(KEYSWITCH_LEFT_THUMB_RIGHTMOST); + + // Pressing KEYSWITCH_TOP_LEFT should fall back to activating the key on layer 0 + state = pressKeyswitchAndCycle(KEYSWITCH_TOP_LEFT); + assertSingleReportThatContains(state, LAYER0_KEY); - sim_.Press(0, 0); // A + // Releasing all keys should generate a single empty report + releaseKeyswitch(KEYSWITCH_TOP_LEFT); + releaseKeyswitch(KEYSWITCH_LEFT_THUMB_RIGHTMOST); state = RunCycle(); - ASSERT_EQ(state->HIDReports()->Keyboard().size(), 1); - EXPECT_THAT( - state->HIDReports()->Keyboard(0).ActiveKeycodes(), - Contains(Key_A)); + assertSingleEmptyReport(state); + + // Afterwards, we should generate no more reports. + state = RunCycle(); + assertNoReport(state); } } // namespace