chore: Add basic tests for studio layer adjustment

This commit is contained in:
Nicolas Münnich 2025-12-21 20:09:00 +00:00
parent a1a7810e78
commit 9359215b1d
21 changed files with 267 additions and 1 deletions

View File

@ -10,4 +10,4 @@ include: two_param.yaml
properties:
bindings:
type: phandle-array
required: true
required: true

View File

@ -0,0 +1,4 @@
s/.*on_add_layer_binding_pressed/add_layer/p
s/.*on_set_layer_binding_at_idx_binding_pressed/set_layer_binding/p
s/.*layer_changed/layer_changed/p
s/.*hid_listener_keycode_//p

View File

@ -0,0 +1,5 @@
-DCONFIG_ZMK_BEHAVIOR_METADATA=y
-DCONFIG_ZMK_BEHAVIOR_LOCAL_IDS=y
-DCONFIG_ZMK_KEYMAP_LAYER_REORDERING=y
-DCONFIG_ZMK_KEYMAP_SETTINGS_STORAGE=y
-DCONFIG_SETTINGS=y

View File

@ -0,0 +1,6 @@
add_layer: Added layer 1
set_layer_binding: Set binding at layer 1, index 0 to binding 1/2
layer_changed: layer 1 state 1 locked 0
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
layer_changed: layer 1 state 0 locked 0

View File

@ -0,0 +1,23 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
// Test adding a layer, setting a binding, activating it, and pressing the binding
&kscan {
events = <
// add a new layer
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// set binding A at layer 1, position 0
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
// activate layer 1 with momentary
ZMK_MOCK_PRESS(1,0,10)
// press position 0 on new layer (should be A)
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// release momentary layer 1
ZMK_MOCK_RELEASE(1,0,10)
>;
};

View File

@ -0,0 +1,32 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/ {
behaviors {
add_layer: add_layer {
compatible = "zmk,behavior-add-layer";
#binding-cells = <0>;
};
set_binding: set_binding {
compatible = "zmk,behavior-set-layer-binding-at-idx";
#binding-cells = <2>;
bindings = <&kp A>, <&kp B>;
};
};
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&add_layer &set_binding 1 0
&mo 1 &kp B>;
};
layer_1 {
status = "reserved";
};
};
};

View File

@ -0,0 +1,3 @@
s/.*layer_changed/layer_changed/p
s/.*hid_listener_keycode_//p
s/.*on_move_layer_binding_pressed/move_layer/p

View File

@ -0,0 +1,5 @@
-DCONFIG_ZMK_BEHAVIOR_METADATA=y
-DCONFIG_ZMK_BEHAVIOR_LOCAL_IDS=y
-DCONFIG_ZMK_KEYMAP_LAYER_REORDERING=y
-DCONFIG_ZMK_KEYMAP_SETTINGS_STORAGE=y
-DCONFIG_SETTINGS=y

View File

@ -0,0 +1,8 @@
move_layer: Moved layer from index 1 to index 2
layer_changed: layer 1 state 1 locked 0
layer_changed: layer 2 state 1 locked 0
pressed: usage_page 0x07 keycode 0x06 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x06 implicit_mods 0x00 explicit_mods 0x00
layer_changed: layer 2 state 0 locked 0
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00

View File

@ -0,0 +1,26 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
// Test moving a layer: swap layers 1 and 2, turn both on,
// press transparent on layer 1 at index 2
// which should fall through to layer 2 at index 1
&kscan {
events = <
// move layer 1 to position 2 (effectively swapping layers 1 and 2)
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// activate layers 1 and 2
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_PRESS(1,1,10)
// press position 0,1 on layer 2 - should output C from layer 2 at index 1
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
// release layer 2 (at index 1)
ZMK_MOCK_RELEASE(1,1,10)
// press position 0,1 again - should output A from default layer
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
>;
};

View File

@ -0,0 +1,34 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/ {
behaviors {
move_layer: move_layer {
compatible = "zmk,behavior-move-layer";
#binding-cells = <2>;
};
};
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&move_layer 1 2 &kp A
&mo 1 &mo 2>;
};
layer_1 {
bindings = <
&kp B &trans
&trans &trans>;
};
layer_2 {
bindings = <
&trans &kp C
&trans &trans>;
};
};
};

View File

@ -0,0 +1,3 @@
s/.*layer_changed/layer_changed/p
s/.*hid_listener_keycode_//p
s/.*on_remove_layer_binding_pressed/remove_layer/p

View File

@ -0,0 +1,5 @@
-DCONFIG_ZMK_BEHAVIOR_METADATA=y
-DCONFIG_ZMK_BEHAVIOR_LOCAL_IDS=y
-DCONFIG_ZMK_KEYMAP_LAYER_REORDERING=y
-DCONFIG_ZMK_KEYMAP_SETTINGS_STORAGE=y
-DCONFIG_SETTINGS=y

View File

@ -0,0 +1,7 @@
remove_layer: Removed layer at index 1
layer_changed: layer 1 state 1 locked 1
pressed: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x04 implicit_mods 0x00 explicit_mods 0x00
layer_changed: layer 2 state 1 locked 1
pressed: usage_page 0x07 keycode 0x06 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x06 implicit_mods 0x00 explicit_mods 0x00

View File

@ -0,0 +1,25 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
// Test removing layer 1
&kscan {
events = <
// remove layer 1
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_RELEASE(1,0,10)
// toggle layer 1 on
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
// press position 0,0 - should output A (layer 0) because layer 1 was removed
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// toggle layer 2 on
ZMK_MOCK_PRESS(1,1,10)
ZMK_MOCK_RELEASE(1,1,10)
// press position 0,0 - should output C (layer 2)
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
>;
};

View File

@ -0,0 +1,34 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
/ {
behaviors {
remove_layer_behavior: remove_layer_behavior {
compatible = "zmk,behavior-remove-layer";
#binding-cells = <1>;
};
};
keymap {
compatible = "zmk,keymap";
default_layer {
bindings = <
&kp A &tog 1
&remove_layer_behavior 1 &tog 2>;
};
layer_1 {
bindings = <
&kp B &tog 1
&remove_layer_behavior 0 &trans>;
};
layer_2 {
bindings = <
&kp C &trans
&none &trans>;
};
};
};

View File

@ -0,0 +1,5 @@
s/.*layer_changed/layer_changed/p
s/.*hid_listener_keycode_//p
s/.*on_remove_layer_binding_pressed/remove_layer/p
s/.*tog_keymap_binding_pressed/tog_pressed/p

View File

@ -0,0 +1,5 @@
-DCONFIG_ZMK_BEHAVIOR_METADATA=y
-DCONFIG_ZMK_BEHAVIOR_LOCAL_IDS=y
-DCONFIG_ZMK_KEYMAP_LAYER_REORDERING=y
-DCONFIG_ZMK_KEYMAP_SETTINGS_STORAGE=y
-DCONFIG_SETTINGS=y

View File

@ -0,0 +1,8 @@
tog_pressed: position 1 layer 1
layer_changed: layer 1 state 1 locked 1
remove_layer: Removed layer at index 0
pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
tog_pressed: position 1 layer 1
pressed: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00
released: usage_page 0x07 keycode 0x05 implicit_mods 0x00 explicit_mods 0x00

View File

@ -0,0 +1,26 @@
#include <dt-bindings/zmk/keys.h>
#include <behaviors.dtsi>
#include <dt-bindings/zmk/kscan_mock.h>
#include "../behavior_keymap.dtsi"
// Test removing layer 0: layer 1 becomes bottom layer
&kscan {
events = <
// toggle layer 1 on
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
// remove layer 0
ZMK_MOCK_PRESS(1,0,10)
ZMK_MOCK_RELEASE(1,0,10)
// press position 0,0 - should output B (layer 1)
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
// try to toggle layer 1 off
ZMK_MOCK_PRESS(0,1,10)
ZMK_MOCK_RELEASE(0,1,10)
// press position 0,0 - should output B
// (layer 1 is now the bottom layer, so shouldn't be disabled)
ZMK_MOCK_PRESS(0,0,10)
ZMK_MOCK_RELEASE(0,0,10)
>;
};

View File

@ -0,0 +1,2 @@
This test fails because the keymap function handling position state changes doesn't work correctly when the default layer is removed.
The iteration loop's end condition is incorrect.