mirror of
https://github.com/qmk/qmk_firmware.git
synced 2025-09-10 17:15:43 +00:00
add combo buffer tests
This commit is contained in:
8
tests/combo/combo_active_buffer/config.h
Normal file
8
tests/combo/combo_active_buffer/config.h
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#define COMBO_BUFFER_LENGTH 2
|
||||
6
tests/combo/combo_active_buffer/test.mk
Normal file
6
tests/combo/combo_active_buffer/test.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
# Copyright 2025 @johnwilmes
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
COMBO_ENABLE = yes
|
||||
|
||||
INTROSPECTION_KEYMAP_C = test_combo_buffer.c
|
||||
37
tests/combo/combo_active_buffer/test_combo.cpp
Normal file
37
tests/combo/combo_active_buffer/test_combo.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "keyboard_report_util.hpp"
|
||||
#include "keycode.h"
|
||||
#include "test_common.h"
|
||||
#include "test_common.hpp"
|
||||
#include "test_driver.hpp"
|
||||
#include "test_fixture.hpp"
|
||||
#include "test_keymap_key.hpp"
|
||||
|
||||
using testing::_;
|
||||
using testing::InSequence;
|
||||
|
||||
extern bool combo_override;
|
||||
|
||||
class ComboBuffer : public TestFixture {};
|
||||
|
||||
TEST_F(ComboBuffer, combo_active_buffer_overflow) {
|
||||
TestDriver driver;
|
||||
KeymapKey key_a(0, 0, 0, KC_A);
|
||||
KeymapKey key_b(0, 1, 0, KC_B);
|
||||
KeymapKey key_c(0, 2, 0, KC_C);
|
||||
KeymapKey key_d(0, 3, 0, KC_D);
|
||||
KeymapKey key_e(0, 4, 0, KC_E);
|
||||
KeymapKey key_f(0, 5, 0, KC_F);
|
||||
set_keymap({key_a, key_b, key_c, key_d, key_e, key_f});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_1));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_2));
|
||||
EXPECT_REPORT(driver, (KC_2));
|
||||
EXPECT_REPORT(driver, (KC_2, KC_3));
|
||||
EXPECT_REPORT(driver, (KC_3));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_combo({key_a, key_b, key_c, key_d, key_e, key_f});
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
18
tests/combo/combo_active_buffer/test_combo_buffer.c
Normal file
18
tests/combo/combo_active_buffer/test_combo_buffer.c
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "quantum.h"
|
||||
#include "stdio.h"
|
||||
|
||||
enum combos {ab_1, cd_2, ef_3};
|
||||
|
||||
uint16_t const ab_1_combo[] = {KC_A, KC_B, COMBO_END};
|
||||
uint16_t const cd_2_combo[] = {KC_C, KC_D, COMBO_END};
|
||||
uint16_t const ef_3_combo[] = {KC_E, KC_F, COMBO_END};
|
||||
|
||||
// clang-format off
|
||||
combo_t key_combos[] = {
|
||||
[ab_1] = COMBO(ab_1_combo, KC_1),
|
||||
[cd_2] = COMBO(cd_2_combo, KC_2),
|
||||
[ef_3] = COMBO(ef_3_combo, KC_3),
|
||||
};
|
||||
// clang-format on
|
||||
9
tests/combo/combo_key_buffer/config.h
Normal file
9
tests/combo/combo_key_buffer/config.h
Normal file
@@ -0,0 +1,9 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#define COMBO_KEY_BUFFER_LENGTH 4
|
||||
#define COMBO_CONTIGUOUS_PER_COMBO
|
||||
6
tests/combo/combo_key_buffer/test.mk
Normal file
6
tests/combo/combo_key_buffer/test.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
# Copyright 2025 @johnwilmes
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
COMBO_ENABLE = yes
|
||||
|
||||
INTROSPECTION_KEYMAP_C = test_combo_key_buffer.c
|
||||
103
tests/combo/combo_key_buffer/test_combo.cpp
Normal file
103
tests/combo/combo_key_buffer/test_combo.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "keyboard_report_util.hpp"
|
||||
#include "keycode.h"
|
||||
#include "test_common.h"
|
||||
#include "test_common.hpp"
|
||||
#include "test_driver.hpp"
|
||||
#include "test_fixture.hpp"
|
||||
#include "test_keymap_key.hpp"
|
||||
|
||||
using testing::_;
|
||||
using testing::InSequence;
|
||||
|
||||
extern bool combo_override;
|
||||
|
||||
class ComboKeyBuffer : public TestFixture {};
|
||||
|
||||
TEST_F(ComboKeyBuffer, combo_key_buffer) {
|
||||
TestDriver driver;
|
||||
KeymapKey key_a(0, 0, 0, KC_A);
|
||||
KeymapKey key_b(0, 1, 0, KC_B);
|
||||
KeymapKey key_i(0, 2, 0, KC_I);
|
||||
KeymapKey key_j(0, 3, 0, KC_J);
|
||||
KeymapKey key_k(0, 4, 0, KC_K);
|
||||
KeymapKey key_a2(0, 5, 0, KC_A);
|
||||
set_keymap({key_a, key_b, key_i, key_j, key_k, key_a2});
|
||||
|
||||
EXPECT_REPORT(driver, (KC_1)).Times(2);
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I, KC_J));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_J));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_combo({key_a, key_i, key_j, key_b});
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
// buffer overflow prevents combo from firing
|
||||
EXPECT_REPORT(driver, (KC_A));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J, KC_K));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J, KC_K, KC_B));
|
||||
EXPECT_REPORT(driver, (KC_I, KC_J, KC_K, KC_B));
|
||||
EXPECT_REPORT(driver, (KC_J, KC_K, KC_B));
|
||||
EXPECT_REPORT(driver, (KC_K, KC_B));
|
||||
EXPECT_REPORT(driver, (KC_B));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_combo({key_a, key_i, key_j, key_k, key_b});
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
// buffer overflow prevents combo from firing initially, fires with a second key press
|
||||
EXPECT_REPORT(driver, (KC_A)).Times(2);
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J, KC_K));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_I, KC_J, KC_K, KC_1));
|
||||
// the first KC_A release is consumed by the active combo even though it is a different position
|
||||
EXPECT_REPORT(driver, (KC_A, KC_J, KC_K, KC_1));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_K, KC_1));
|
||||
EXPECT_REPORT(driver, (KC_A, KC_1));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
for (KeymapKey key : {key_a, key_i, key_j, key_k, key_b, key_a2}) {
|
||||
key.press();
|
||||
run_one_scan_loop();
|
||||
}
|
||||
for (KeymapKey key : {key_a, key_i, key_j, key_k, key_b, key_a2}) {
|
||||
key.release();
|
||||
run_one_scan_loop();
|
||||
}
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
|
||||
TEST_F(ComboKeyBuffer, combo_key_buffer_blocked) {
|
||||
TestDriver driver;
|
||||
KeymapKey key_a(0, 0, 0, KC_A);
|
||||
KeymapKey key_b(0, 1, 0, KC_B);
|
||||
KeymapKey key_i(0, 2, 0, KC_I);
|
||||
KeymapKey key_j(0, 3, 0, KC_J);
|
||||
KeymapKey key_k(0, 4, 0, KC_K);
|
||||
KeymapKey key_x(0, 5, 0, KC_X);
|
||||
set_keymap({key_a, key_b, key_i, key_j, key_k, key_x});
|
||||
|
||||
// If the key buffer doesn't overflow, we wait for ABX to fire
|
||||
EXPECT_REPORT(driver, (KC_2)).Times(2);
|
||||
EXPECT_REPORT(driver, (KC_I, KC_2));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_combo({key_a, key_b, key_i, key_x});
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
|
||||
// If the key buffer overflows, we just use AB
|
||||
EXPECT_REPORT(driver, (KC_1));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I, KC_J));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I, KC_J, KC_K));
|
||||
EXPECT_REPORT(driver, (KC_1, KC_I, KC_J, KC_K, KC_X));
|
||||
EXPECT_REPORT(driver, (KC_I, KC_J, KC_K, KC_X));
|
||||
EXPECT_REPORT(driver, (KC_J, KC_K, KC_X));
|
||||
EXPECT_REPORT(driver, (KC_K, KC_X));
|
||||
EXPECT_REPORT(driver, (KC_X));
|
||||
EXPECT_EMPTY_REPORT(driver);
|
||||
tap_combo({key_a, key_b, key_i, key_j, key_k, key_x});
|
||||
VERIFY_AND_CLEAR(driver);
|
||||
}
|
||||
23
tests/combo/combo_key_buffer/test_combo_key_buffer.c
Normal file
23
tests/combo/combo_key_buffer/test_combo_key_buffer.c
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2025 @johnwilmes
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#include "quantum.h"
|
||||
#include "stdio.h"
|
||||
|
||||
enum combos {ab_1, abx_2};
|
||||
|
||||
uint16_t const ab_1_combo[] = {KC_A, KC_B, COMBO_END};
|
||||
uint16_t const abx_2_combo[] = {KC_A, KC_B, KC_X, COMBO_END};
|
||||
|
||||
// clang-format off
|
||||
combo_t key_combos[] = {
|
||||
[ab_1] = COMBO(ab_1_combo, KC_1),
|
||||
[abx_2] = COMBO(abx_2_combo, KC_2),
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
bool is_combo_contiguous(uint16_t index, combo_t *combo, keyrecord_t *record, uint8_t n_unpressed_keys) {
|
||||
return false; // No combos are contiguous in this test
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user