summaryrefslogtreecommitdiffstats
path: root/nixos/tests/keyd.nix
blob: 81576fac2346c92b6a3c6b8ad4eea32da823b6f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# The test template is taken from the `./keymap.nix`
{
  pkgs,
  runTest,
  lib,
}:

let
  readyFile = "/tmp/readerReady";
  resultFile = "/tmp/readerResult";

  testReader = pkgs.writeScript "test-input-reader" ''
    rm -f ${resultFile} ${resultFile}.tmp
    logger "testReader: START: Waiting for $1 characters, expecting '$2'."
    touch ${readyFile}
    read -r -N $1 chars
    rm -f ${readyFile}
    if [ "$chars" == "$2" ]; then
      logger -s "testReader: PASS: Got '$2' as expected." 2>${resultFile}.tmp
    else
      logger -s "testReader: FAIL: Expected '$2' but got '$chars'." 2>${resultFile}.tmp
    fi
    # rename after the file is written to prevent a race condition
    mv  ${resultFile}.tmp ${resultFile}
  '';

  mkKeyboardTest =
    name:
    { default, test }:

    runTest {
      inherit name;

      nodes.machine = {
        services.keyd = {
          enable = true;
          keyboards = { inherit default; };
        };
      };

      testScript = ''
        import shlex

        machine.wait_for_unit("keyd.service")

        def run_test_case(cmd, test_case_name, inputs, expected):
            with subtest(test_case_name):
                assert len(inputs) == len(expected)
                machine.execute("rm -f ${readyFile} ${resultFile}")
                # set up process that expects all the keys to be entered
                machine.succeed(
                    "{} {} {} {} >&2 &".format(
                        cmd,
                        "${testReader}",
                        len(inputs),
                        shlex.quote("".join(expected)),
                    )
                )
                # wait for reader to be ready
                machine.wait_for_file("${readyFile}")
                # send all keys
                for key in inputs:
                    machine.send_key(key)
                # wait for result and check
                machine.wait_for_file("${resultFile}")
                machine.succeed("grep -q 'PASS:' ${resultFile}")
        test = ${builtins.toJSON test}
        run_test_case("openvt -sw --", "${name}", test["press"], test["expect"])
      '';
    };

in
lib.mapAttrs mkKeyboardTest {
  swap-ab_and_ctrl-as-shift = {
    test.press = [
      "a"
      "ctrl-b"
      "c"
      "alt_r-h"
    ];
    test.expect = [
      "b"
      "A"
      "c"
      "q"
    ];

    default = {
      settings.main = {
        "a" = "b";
        "b" = "a";
        "control" = "oneshot(shift)";
        "rightalt" = "layer(rightalt)";
      };
      extraConfig = ''
        [rightalt:G]
        h = q
      '';
    };
  };
}