Speed up unit tests

This commit is contained in:
xs5871 2023-03-08 20:14:24 +00:00 committed by xs5871
parent fd700cff44
commit 47fe859e11
7 changed files with 107 additions and 74 deletions

View File

@ -23,6 +23,8 @@ def code2name(code):
class KeyboardTest: class KeyboardTest:
loop_delay_ms = 2
def __init__( def __init__(
self, self,
modules, modules,
@ -128,4 +130,4 @@ class KeyboardTest:
def do_main_loop(self): def do_main_loop(self):
self.keyboard._main_loop() self.keyboard._main_loop()
time.sleep(0.002) time.sleep(self.loop_delay_ms / 1000)

View File

@ -10,7 +10,7 @@ from tests.keyboard_test import KeyboardTest
class TestCapsWord(unittest.TestCase): class TestCapsWord(unittest.TestCase):
def setUp(self): def setUp(self):
self.kb = KeyboardTest( self.kb = KeyboardTest(
[CapsWord()], [CapsWord(timeout=2 * KeyboardTest.loop_delay_ms)],
[ [
[KC.CW, KC.A, KC.Z, KC.N1, KC.N0, KC.SPC], [KC.CW, KC.A, KC.Z, KC.N1, KC.N0, KC.SPC],
], ],

View File

@ -1,28 +1,36 @@
import unittest import unittest
from kmk.keys import KC from kmk.keys import KC
from kmk.modules.combos import Chord, Combos, Sequence from kmk.modules.combos import Chord, Combo, Combos, Sequence
from kmk.modules.layers import Layers from kmk.modules.layers import Layers
from tests.keyboard_test import KeyboardTest from tests.keyboard_test import KeyboardTest
class TestCombo(unittest.TestCase): class TestCombo(unittest.TestCase):
def setUp(self): def setUp(self):
self.t_within = 2 * KeyboardTest.loop_delay_ms
self.t_after = 7 * KeyboardTest.loop_delay_ms
timeout = (self.t_after + self.t_within) // 2
# overide default timeouts
Combo.timeout = timeout
Sequence.timeout = timeout
combos = Combos() combos = Combos()
layers = Layers() layers = Layers()
KCMO = KC.MO(1) KCMO = KC.MO(1)
combos.combos = [ combos.combos = [
Chord((KC.A, KC.B, KC.C), KC.Y), Chord((KC.A, KC.B, KC.C), KC.Y),
Chord((KC.A, KC.B), KC.X), Chord((KC.A, KC.B), KC.X),
Chord((KC.C, KC.D), KC.Z, timeout=80), Chord((KC.C, KC.D), KC.Z, timeout=2 * timeout),
Chord((KC.C, KCMO), KC.Z), Chord((KC.C, KCMO), KC.Z),
Chord((KC.F, KC.G), KC.Z, timeout=130), Chord((KC.F, KC.G), KC.Z, timeout=3 * timeout),
Sequence((KC.N1, KC.N2, KC.N3), KC.Y, timeout=50), Sequence((KC.N1, KC.N2, KC.N3), KC.Y),
Sequence((KC.N1, KC.N2), KC.X, timeout=50), Sequence((KC.N1, KC.N2), KC.X),
Sequence((KC.N3, KC.N4), KC.Z, timeout=100), Sequence((KC.N3, KC.N4), KC.Z, timeout=2 * timeout),
Sequence((KC.N1, KC.N1, KC.N1), KC.W, timeout=50), Sequence((KC.N1, KC.N1, KC.N1), KC.W),
Sequence((KC.N3, KC.N2, KC.N1), KC.Y, timeout=50, fast_reset=False), Sequence((KC.N3, KC.N2, KC.N1), KC.Y, fast_reset=False),
Sequence((KC.LEADER, KC.N1), KC.V, timeout=50), Sequence((KC.LEADER, KC.N1), KC.V),
] ]
self.keyboard = KeyboardTest( self.keyboard = KeyboardTest(
[combos, layers], [combos, layers],
@ -33,9 +41,6 @@ class TestCombo(unittest.TestCase):
debug_enabled=False, debug_enabled=False,
) )
self.t_within = 40
self.t_after = 60
def test_chord(self): def test_chord(self):
keyboard = self.keyboard keyboard = self.keyboard
t_within = self.t_within t_within = self.t_within

View File

@ -10,20 +10,37 @@ class TestHoldTap(unittest.TestCase):
def setUp(self): def setUp(self):
KC.clear() KC.clear()
self.t_within = 2 * KeyboardTest.loop_delay_ms
self.t_after = 5 * KeyboardTest.loop_delay_ms
tap_time = (self.t_after + self.t_within) // 2
# overide default timeouts
HoldTap.tap_time = tap_time
def test_holdtap(self): def test_holdtap(self):
t_within = self.t_within
t_after = self.t_after
keyboard = KeyboardTest( keyboard = KeyboardTest(
[Layers(), HoldTap()], [Layers(), HoldTap()],
[ [
[KC.HT(KC.A, KC.LCTL), KC.LT(1, KC.B), KC.C, KC.D], [
KC.HT(KC.A, KC.LCTL),
KC.LT(1, KC.B),
KC.C,
KC.D,
],
[KC.N1, KC.N2, KC.N3, KC.N4], [KC.N1, KC.N2, KC.N3, KC.N4],
], ],
debug_enabled=False, debug_enabled=False,
) )
keyboard.test('HT tap behaviour', [(0, True), 100, (0, False)], [{KC.A}, {}]) keyboard.test(
'HT tap behaviour', [(0, True), t_within, (0, False)], [{KC.A}, {}]
)
keyboard.test( keyboard.test(
'HT hold behaviour', [(0, True), 350, (0, False)], [{KC.LCTL}, {}] 'HT hold behaviour', [(0, True), t_after, (0, False)], [{KC.LCTL}, {}]
) )
# TODO test multiple mods being held # TODO test multiple mods being held
@ -31,74 +48,74 @@ class TestHoldTap(unittest.TestCase):
# HT # HT
keyboard.test( keyboard.test(
'HT within tap time sequential -> tap behavior', 'HT within tap time sequential -> tap behavior',
[(0, True), 100, (0, False), (3, True), (3, False)], [(0, True), t_within, (0, False), (3, True), (3, False)],
[{KC.A}, {}, {KC.D}, {}], [{KC.A}, {}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'HT within tap time rolling -> hold behavior', 'HT within tap time rolling -> hold behavior',
[(0, True), 100, (3, True), 250, (0, False), (3, False)], [(0, True), t_within, (3, True), t_after, (0, False), (3, False)],
[{KC.LCTL}, {KC.LCTL, KC.D}, {KC.D}, {}], [{KC.LCTL}, {KC.LCTL, KC.D}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'HT within tap time nested -> hold behavior', 'HT within tap time nested -> hold behavior',
[(0, True), 100, (3, True), (3, False), 250, (0, False)], [(0, True), t_within, (3, True), (3, False), t_after, (0, False)],
[{KC.LCTL}, {KC.LCTL, KC.D}, {KC.LCTL}, {}], [{KC.LCTL}, {KC.LCTL, KC.D}, {KC.LCTL}, {}],
) )
keyboard.test( keyboard.test(
'HT after tap time sequential -> hold behavior', 'HT after tap time sequential -> hold behavior',
[(0, True), 350, (0, False), (3, True), (3, False)], [(0, True), t_after, (0, False), (3, True), (3, False)],
[{KC.LCTL}, {}, {KC.D}, {}], [{KC.LCTL}, {}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'HT after tap time rolling -> hold behavior', 'HT after tap time rolling -> hold behavior',
[(0, True), 350, (3, True), (0, False), (3, False)], [(0, True), t_after, (3, True), (0, False), (3, False)],
[{KC.LCTL}, {KC.LCTL, KC.D}, {KC.D}, {}], [{KC.LCTL}, {KC.LCTL, KC.D}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'HT after tap time nested -> hold behavior', 'HT after tap time nested -> hold behavior',
[(0, True), 350, (3, True), (3, False), (0, False)], [(0, True), t_after, (3, True), (3, False), (0, False)],
[{KC.LCTL}, {KC.LCTL, KC.D}, {KC.LCTL}, {}], [{KC.LCTL}, {KC.LCTL, KC.D}, {KC.LCTL}, {}],
) )
# LT # LT
keyboard.test( keyboard.test(
'LT within tap time sequential -> tap behavior', 'LT within tap time sequential -> tap behavior',
[(1, True), 100, (1, False), (3, True), (3, False)], [(1, True), t_within, (1, False), (3, True), (3, False)],
[{KC.B}, {}, {KC.D}, {}], [{KC.B}, {}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'LT within tap time rolling -> tap behavior', 'LT within tap time rolling -> tap behavior',
[(1, True), 100, (3, True), 250, (1, False), (3, False)], [(1, True), t_within, (3, True), t_after, (1, False), (3, False)],
[{KC.B}, {KC.B, KC.D}, {KC.D}, {}], [{KC.B}, {KC.B, KC.D}, {KC.D}, {}],
) )
keyboard.test( keyboard.test(
'LT within tap time nested -> tap behavior', 'LT within tap time nested -> tap behavior',
[(1, True), 100, (3, True), (3, False), 250, (1, False)], [(1, True), t_within, (3, True), (3, False), t_after, (1, False)],
[{KC.B}, {KC.B, KC.D}, {KC.B}, {}], [{KC.B}, {KC.B, KC.D}, {KC.B}, {}],
) )
keyboard.test( keyboard.test(
'LT after tap time sequential -> hold behavior', 'LT after tap time sequential -> hold behavior',
[(1, True), 350, (1, False), (3, True), (3, False)], [(1, True), t_after, (1, False), (3, True), (3, False)],
[{KC.D}, {}], [{KC.D}, {}],
) )
keyboard.test( keyboard.test(
'LT after tap time rolling -> hold behavior', 'LT after tap time rolling -> hold behavior',
[(1, True), 350, (3, True), (1, False), (3, False)], [(1, True), t_after, (3, True), (1, False), (3, False)],
[{KC.N4}, {}], [{KC.N4}, {}],
) )
keyboard.test( keyboard.test(
'LT after tap time nested -> hold behavior', 'LT after tap time nested -> hold behavior',
[(1, True), 350, (3, True), (3, False), (1, False)], [(1, True), t_after, (3, True), (3, False), (1, False)],
[{KC.N4}, {}], [{KC.N4}, {}],
) )
@ -106,9 +123,9 @@ class TestHoldTap(unittest.TestCase):
'LT after tap time nested -> hold behavior', 'LT after tap time nested -> hold behavior',
[ [
(0, True), (0, True),
350, t_after,
(1, True), (1, True),
350, t_after,
(3, True), (3, True),
(3, False), (3, False),
(1, False), (1, False),
@ -118,26 +135,25 @@ class TestHoldTap(unittest.TestCase):
) )
def test_holdtap_chain(self): def test_holdtap_chain(self):
t_after = self.t_after
keyboard = KeyboardTest( keyboard = KeyboardTest(
[HoldTap()], [HoldTap()],
[ [
[ [
KC.N0, KC.N0,
KC.HT(KC.N1, KC.LCTL, tap_time=50), KC.HT(KC.N1, KC.LCTL),
KC.HT(KC.N2, KC.LSFT, tap_interrupted=True, tap_time=50), KC.HT(KC.N2, KC.LSFT, tap_interrupted=True),
KC.HT( KC.HT(
KC.N3, KC.N3,
KC.LALT, KC.LALT,
prefer_hold=False, prefer_hold=False,
tap_interrupted=True, tap_interrupted=True,
tap_time=50,
), ),
], ],
], ],
debug_enabled=False, debug_enabled=False,
) )
# t_within = 40
t_after = 60
keyboard.test( keyboard.test(
'chained 0', 'chained 0',
@ -275,21 +291,21 @@ class TestHoldTap(unittest.TestCase):
# TODO test TT # TODO test TT
def test_holdtap_repeat(self): def test_holdtap_repeat(self):
t_within = self.t_within
t_after = self.t_after
keyboard = KeyboardTest( keyboard = KeyboardTest(
[HoldTap()], [HoldTap()],
[ [
[ [
KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.ALL, tap_time=50), KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.ALL),
KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.TAP, tap_time=50), KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.TAP),
KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.HOLD, tap_time=50), KC.HT(KC.A, KC.B, repeat=HoldTapRepeat.HOLD),
] ]
], ],
debug_enabled=False, debug_enabled=False,
) )
t_within = 40
t_after = 60
keyboard.test( keyboard.test(
'repeat tap', 'repeat tap',
[ [

View File

@ -6,25 +6,30 @@ from kmk.modules.oneshot import OneShot
from tests.keyboard_test import KeyboardTest from tests.keyboard_test import KeyboardTest
class TestHoldTap(unittest.TestCase): class TestOneshot(unittest.TestCase):
def test_oneshot(self): def test_oneshot(self):
t_within = 2 * KeyboardTest.loop_delay_ms
t_after = 7 * KeyboardTest.loop_delay_ms
timeout = (t_after + t_within) // 2
# overide default timeouts
OneShot.tap_time = timeout
keyboard = KeyboardTest( keyboard = KeyboardTest(
[Layers(), OneShot()], [Layers(), OneShot()],
[ [
[ [
KC.OS(KC.MO(1), tap_time=50), KC.OS(KC.MO(1)),
KC.MO(1), KC.MO(1),
KC.C, KC.C,
KC.D, KC.D,
KC.OS(KC.E, tap_time=50), KC.OS(KC.E),
KC.OS(KC.F, tap_time=50), KC.OS(KC.F),
], ],
[KC.N0, KC.N1, KC.N2, KC.N3, KC.OS(KC.LSFT, tap_time=50), KC.TRNS], [KC.N0, KC.N1, KC.N2, KC.N3, KC.OS(KC.LSFT), KC.TRNS],
], ],
debug_enabled=False, debug_enabled=False,
) )
t_within = 40
t_after = 60
keyboard.test( keyboard.test(
'OS timed out', 'OS timed out',

View File

@ -37,11 +37,8 @@ class TestStickyMod(unittest.TestCase):
[ [
(4, True), (4, True),
(4, False), (4, False),
100,
(4, True), (4, True),
200,
(4, False), (4, False),
100,
(1, True), (1, True),
(1, False), (1, False),
], ],
@ -61,26 +58,19 @@ class TestStickyMod(unittest.TestCase):
(1, True), (1, True),
(1, False), (1, False),
(2, True), (2, True),
200,
(0, True), (0, True),
50,
(0, False), (0, False),
50,
(0, True), (0, True),
50,
(0, False), (0, False),
(1, True), (1, True),
(1, False), (1, False),
50,
(1, True), (1, True),
(1, False), (1, False),
(0, True), (0, True),
50,
(0, False), (0, False),
(3, True), (3, True),
(3, False), (3, False),
(2, False), (2, False),
100,
(4, True), (4, True),
(4, False), (4, False),
(1, True), (1, True),

View File

@ -7,6 +7,7 @@ from tests.keyboard_test import KeyboardTest
class TestStringSubstitution(unittest.TestCase): class TestStringSubstitution(unittest.TestCase):
def setUp(self) -> None: def setUp(self) -> None:
self.delay = KeyboardTest.loop_delay_ms
self.symbols = '`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<>?' self.symbols = '`-=[]\\;\',./~!@#$%^&*()_+{}|:\"<>?'
self.everything = ALL_NUMBERS + ALL_ALPHAS + ALL_ALPHAS.lower() + self.symbols self.everything = ALL_NUMBERS + ALL_ALPHAS + ALL_ALPHAS.lower() + self.symbols
self.test_dictionary = { self.test_dictionary = {
@ -46,21 +47,21 @@ class TestStringSubstitution(unittest.TestCase):
# that results in a corresponding match, as that key is never sent # that results in a corresponding match, as that key is never sent
self.keyboard.test( self.keyboard.test(
'multi-character key, single-character value', 'multi-character key, single-character value',
[(0, True), (0, False), (0, True), (0, False), 50], [(0, True), (0, False), (0, True), (0, False), self.delay],
[{KC.A}, {}, {KC.BACKSPACE}, {}, {KC.B}, {}], [{KC.A}, {}, {KC.BACKSPACE}, {}, {KC.B}, {}],
) )
# note: the pressed key is never sent here, as the event is # note: the pressed key is never sent here, as the event is
# intercepted and the replacement is sent instead # intercepted and the replacement is sent instead
self.keyboard.test( self.keyboard.test(
'multi-character value, single-character key', 'multi-character value, single-character key',
[(1, True), (1, False), 50], [(1, True), (1, False), self.delay],
[{KC.A}, {}, {KC.A}, {}], [{KC.A}, {}, {KC.A}, {}],
) )
# modifiers are force-released if there's a match, # modifiers are force-released if there's a match,
# so the keyup event for them isn't sent # so the keyup event for them isn't sent
self.keyboard.test( self.keyboard.test(
'shifted alphanumeric or symbol in key and/or value', 'shifted alphanumeric or symbol in key and/or value',
[(3, True), (2, True), (2, False), (3, False), 50], [(3, True), (2, True), (2, False), (3, False), self.delay],
[{KC.LSHIFT}, {KC.LSHIFT, KC.N2}, {}], [{KC.LSHIFT}, {KC.LSHIFT, KC.N2}, {}],
) )
self.keyboard.test( self.keyboard.test(
@ -74,7 +75,7 @@ class TestStringSubstitution(unittest.TestCase):
(5, False), (5, False),
(5, True), (5, True),
(5, False), (5, False),
10, self.delay,
], ],
[ [
{KC.D}, {KC.D},
@ -93,7 +94,7 @@ class TestStringSubstitution(unittest.TestCase):
) )
self.keyboard.test( self.keyboard.test(
'the presence of non-shift modifiers prevents a multi-character match', 'the presence of non-shift modifiers prevents a multi-character match',
[(4, True), (0, True), (0, False), (0, True), (0, False), (4, False), 50], [(4, True), (0, True), (0, False), (0, True), (0, False), (4, False)],
[ [
{KC.LCTRL}, {KC.LCTRL},
{KC.LCTRL, KC.A}, {KC.LCTRL, KC.A},
@ -105,7 +106,7 @@ class TestStringSubstitution(unittest.TestCase):
) )
self.keyboard.test( self.keyboard.test(
'the presence of non-shift modifiers prevents a single-character match', 'the presence of non-shift modifiers prevents a single-character match',
[(4, True), (1, True), (1, False), (4, False), 50], [(4, True), (1, True), (1, False), (4, False)],
[ [
{KC.LCTRL}, {KC.LCTRL},
{KC.LCTRL, KC.B}, {KC.LCTRL, KC.B},
@ -115,7 +116,7 @@ class TestStringSubstitution(unittest.TestCase):
) )
self.keyboard.test( self.keyboard.test(
'the presence of non-shift modifiers resets current potential matches', 'the presence of non-shift modifiers resets current potential matches',
[(0, True), (0, False), (4, True), (0, True), (0, False), (4, False), 50], [(0, True), (0, False), (4, True), (0, True), (0, False), (4, False)],
[ [
{KC.A}, {KC.A},
{}, {},
@ -128,7 +129,15 @@ class TestStringSubstitution(unittest.TestCase):
self.keyboard.test( self.keyboard.test(
'match found and replaced when there are preceding characters', 'match found and replaced when there are preceding characters',
[(5, True), (5, False), (0, True), (0, False), (0, True), (0, False), 50], [
(5, True),
(5, False),
(0, True),
(0, False),
(0, True),
(0, False),
self.delay,
],
[ [
{KC.C}, {KC.C},
{}, {},
@ -142,7 +151,15 @@ class TestStringSubstitution(unittest.TestCase):
) )
self.keyboard.test( self.keyboard.test(
'match found and replaced when there are trailing characters, and the trailing characters are sent', 'match found and replaced when there are trailing characters, and the trailing characters are sent',
[(0, True), (0, False), (0, True), (0, False), (5, True), (5, False), 50], [
(0, True),
(0, False),
(0, True),
(0, False),
(5, True),
(5, False),
self.delay,
],
[ [
{KC.A}, {KC.A},
{}, {},
@ -156,7 +173,7 @@ class TestStringSubstitution(unittest.TestCase):
) )
self.keyboard.test( self.keyboard.test(
'no match', 'no match',
[(0, True), (0, False), (2, True), (2, False), 50], [(0, True), (0, False), (2, True), (2, False)],
[ [
{KC.A}, {KC.A},
{}, {},
@ -183,7 +200,7 @@ class TestStringSubstitution(unittest.TestCase):
(6, False), (6, False),
(0, True), (0, True),
(0, False), (0, False),
50, 10 * self.delay,
], ],
[ [
{KC.D}, {KC.D},
@ -241,7 +258,7 @@ class TestStringSubstitution(unittest.TestCase):
# send the unreachable match "cccc" after matching "ccc" # send the unreachable match "cccc" after matching "ccc"
(5, True), (5, True),
(5, False), (5, False),
10, self.delay,
], ],
[ [
{KC.C}, {KC.C},
@ -272,7 +289,7 @@ class TestStringSubstitution(unittest.TestCase):
(0, True), (0, True),
(0, False), (0, False),
(7, False), (7, False),
10, self.delay,
], ],
[ [
{KC.RSHIFT}, {KC.RSHIFT},
@ -303,7 +320,6 @@ class TestStringSubstitution(unittest.TestCase):
(0, False), (0, False),
(4, False), (4, False),
(8, False), (8, False),
10,
], ],
[ [
{KC.RALT}, {KC.RALT},
@ -325,7 +341,6 @@ class TestStringSubstitution(unittest.TestCase):
(1, False), (1, False),
(3, False), (3, False),
(8, False), (8, False),
10,
], ],
[ [
{KC.RALT}, {KC.RALT},