1#!/usr/bin/env python3
2#
3# Call with pytest. Requires XKB_CONFIG_ROOT to be set
4
5import os
6import pytest
7import subprocess
8import sys
9from pathlib import Path
10
11
12def _xkb_config_root():
13    path = os.getenv('XKB_CONFIG_ROOT')
14    assert path is not None, 'Environment variable XKB_CONFIG_ROOT must be set'
15    print(f'Using {path}')
16
17    xkbpath = Path(path)
18    assert (xkbpath / 'symbols').exists(), f'{path} is not an XKB installation'
19    return xkbpath
20
21
22@pytest.fixture
23def xkb_config_root():
24    return _xkb_config_root()
25
26
27def pytest_generate_tests(metafunc):
28    # for any test_foo function with an argument named xkb_symbols,
29    # make it a list of tuples in the form (us, dvorak)
30    # The list is generated by scanning all xkb symbol files and extracting the
31    # various sections
32    if 'xkb_symbols' in metafunc.fixturenames:
33
34        xkb_symbols = []
35        # This skips the *_vndr directories, they're harder to test
36        for symbols_file in _xkb_config_root().glob('symbols/*'):
37            if symbols_file.is_dir():
38                continue
39            with open(symbols_file) as f:
40                print(f'Found file {symbols_file}')
41                for line in f:
42                    if not line.startswith('xkb_symbols "'):
43                        continue
44                    section = line.split('"')[1]
45                    xkb_symbols.append((symbols_file.name, section))
46        assert xkb_symbols
47        metafunc.parametrize('xkb_symbols', xkb_symbols)
48
49
50def test_xkbcomp(xkb_config_root, xkb_symbols):
51    layout, variant = xkb_symbols
52    keymap = '''
53xkb_keymap {
54        xkb_keycodes  { include "evdev+aliases(qwerty)" };
55        xkb_types     { include "complete"      };
56        xkb_compat    { include "complete"      };
57        xkb_symbols   { include "pc+%s(%s)"     };
58};
59''' % (layout, variant)
60    print(keymap)
61
62    args = [
63        'xkbcomp',
64        '-w0',      # reduce warning nose
65        '-xkb',
66        '-I',       # disable system includes
67        f'-I{xkb_config_root}',
68        '-', '-',   # from stdin, to stdout
69    ]
70    p = subprocess.run(args, input=keymap, encoding='utf-8', capture_output=True)
71    if p.stderr:
72        print(p.stderr, file=sys.stderr)
73    if p.returncode != 0:
74        print(p.stdout)
75    if p.returncode < 0:
76        print(f'xkbcomp exited with signal {-p.returncode}', file=sys.stderr)
77
78    assert p.returncode == 0
79