Exemple #1
0
 def test_syntax_error(self):
     for combo_string in (
         # Invalid character.
         'Return,',
         'Return&',
         'Ret. urn <',
         'exclam ! foo',
         'shift[a]',
         # Unbalanced )
         ') arg',
         'arg )',
         'arg())',
         'arg(x) )',
         # Unbalanced (
         'test(',
         '( grr',
         'foo ( bar',
         'foo (bar ( ',
         'foo ((',
     ):
         msg = 'parse_key_combo(%r): SyntaxError not raised' % (
             combo_string,
         )
         with self.assertRaisesWithMessage(SyntaxError, msg):
             parse_key_combo(combo_string)
Exemple #2
0
def test_key_combo(key_name_to_key_code, instructions):
    def repr_expected(result):
        assert isinstance(result, str)
        return [s.strip() for s in result.split()]

    def repr_key_events(events):
        assert isinstance(events, list)
        return [
            '%s%s' % ('+' if pressed else '-', key) for key, pressed in events
        ]

    for action, *args in instructions:
        if action == 'parse':
            combo_string, key_events = args
            if inspect.isclass(key_events):
                with pytest.raises(key_events):
                    parse_key_combo(combo_string,
                                    key_name_to_key_code=key_name_to_key_code)
            else:
                assert repr_key_events(
                    parse_key_combo(combo_string,
                                    key_name_to_key_code=key_name_to_key_code)
                ) == repr_expected(key_events)
        else:
            raise ValueError(args[0])
Exemple #3
0
 def test_bad_keyname(self):
     name2code = { c: c for c in '123abc' }
     combo_string = '1 (c) 2 bad 3 (a b c)'
     msg = 'parse_key_combo(%r): ValueError not raised' % (
         combo_string,
     )
     with self.assertRaisesWithMessage(ValueError, msg):
         parse_key_combo(combo_string, key_name_to_key_code=name2code.get)
Exemple #4
0
 def test_already_pressed(self):
     for combo_string in (
             # Pressing an already pressed key.
             'foo(foo)',
             'Foo(foO)',
             'foo(fOo(arg))',
             'foo(bar(Foo))',
             'foo(bar(foo(x)))',
     ):
         msg = 'parse_key_combo(%r): ValueError not raised' % (
             combo_string, )
         with self.assertRaisesWithMessage(ValueError, msg):
             parse_key_combo(combo_string)
Exemple #5
0
 def test_already_pressed(self):
     for combo_string in (
         # Pressing an already pressed key.
         'foo(foo)',
         'Foo(foO)',
         'foo(fOo(arg))',
         'foo(bar(Foo))',
         'foo(bar(foo(x)))',
     ):
         msg = 'parse_key_combo(%r): ValueError not raised' % (
             combo_string,
         )
         with self.assertRaisesWithMessage(ValueError, msg):
             parse_key_combo(combo_string)
Exemple #6
0
 def test_stacking(self):
     for combo_string_variants, expected in (
         # + press, - release
         # 1 is not a valid identifier, but still a valid key name.
         (('1',)                    , '+1 -1'                                                  ),
         (('Shift_l', 'SHIFT_L')    , '+shift_l -shift_l'                                      ),
         # Case does not matter.
         (('a', ' A ')              , '+a -a'                                                  ),
         (('a(b c)', 'a ( b c   )') , '+a +b -b +c -c -a'                                      ),
         (('a(bc)', ' a(  Bc )')    , '+a +bc -bc -a'                                          ),
         (('a(bc(d)e f(g) h())i j',), '+a +bc +d -d -bc +e -e +f +g -g -f +h -h -a +i -i +j -j'),
         (('foo () bar ( foo a b c (d))',
           'fOo () Bar ( FOO a B c (D))'),
          '+foo -foo +bar +foo -foo +a -a +b -b +c +d -d -c -bar'),
     ):
         expected = [s.strip() for s in expected.split()]
         for combo_string in combo_string_variants:
             result = ['%s%s' % ('+' if pressed else '-', key)
                       for key, pressed in parse_key_combo(combo_string)]
             msg = (
                 'parse_key_combo(%r):\n'
                 ' result  : %r\n'
                 ' expected: %r\n'
                 % (combo_string, result, expected)
             )
             self.assertEqual(result, expected, msg=msg)
Exemple #7
0
 def test_stacking(self):
     for combo_string_variants, expected in (
             # + press, - release
             # 1 is not a valid identifier, but still a valid key name.
         (('1', ), '+1 -1'),
         (('Shift_l', 'SHIFT_L'), '+shift_l -shift_l'),
             # Case does not matter.
         (('a', ' A '), '+a -a'),
         (('a(b c)', 'a ( b c   )'), '+a +b -b +c -c -a'),
         (('a(bc)', ' a(  Bc )'), '+a +bc -bc -a'),
         (('a(bc(d)e f(g) h())i j', ),
          '+a +bc +d -d -bc +e -e +f +g -g -f +h -h -a +i -i +j -j'),
         (('foo () bar ( foo a b c (d))', 'fOo () Bar ( FOO a B c (D))'),
          '+foo -foo +bar +foo -foo +a -a +b -b +c +d -d -c -bar'),
     ):
         expected = [s.strip() for s in expected.split()]
         for combo_string in combo_string_variants:
             result = [
                 '%s%s' % ('+' if pressed else '-', key)
                 for key, pressed in parse_key_combo(combo_string)
             ]
             msg = ('parse_key_combo(%r):\n'
                    ' result  : %r\n'
                    ' expected: %r\n' % (combo_string, result, expected))
             self.assertEqual(result, expected, msg=msg)
    def send_key_combination(self, combo_string):
        """Emulate a sequence of key combinations.

        Args:
            combo_string: A string representing a sequence of key
                combinations. Keys are represented by their names in the
                Xlib.XK module, without the 'XK_' prefix. For example, the
                left Alt key is represented by 'Alt_L'. Keys are either
                separated by a space or a left or right parenthesis.
                Parentheses must be properly formed in pairs and may be
                nested. A key immediately followed by a parenthetical
                indicates that the key is pressed down while all keys enclosed
                in the parenthetical are pressed and released in turn. For
                example, Alt_L(Tab) means to hold the left Alt key down, press
                and release the Tab key, and then release the left Alt key.

        """
        def name_to_code(name):
            code = KEYNAME_TO_KEYCODE.get(name)
            if code is not None:
                return code
            char = KEYNAME_TO_CHAR.get(name, name)
            code, mods = mac_keycode.KeyCodeForChar(char)[0]
            return code
        # Parse and validate combo.
        key_events = parse_key_combo(combo_string, name_to_code)
        # Send events...
        self._send_sequence(key_events)
Exemple #9
0
def test_key_combo(key_name_to_key_code, instructions):
    def repr_expected(result):
        assert isinstance(result, str)
        return [s.strip() for s in result.split()]
    def repr_key_events(events):
        assert isinstance(events, list)
        return ['%s%s' % ('+' if pressed else '-', key)
                for key, pressed in events]
    for action, *args in instructions:
        if action == 'parse':
            combo_string, key_events = args
            if inspect.isclass(key_events):
                with pytest.raises(key_events):
                    parse_key_combo(combo_string, key_name_to_key_code=key_name_to_key_code)
            else:
                assert repr_key_events(parse_key_combo(combo_string, key_name_to_key_code=key_name_to_key_code)) == repr_expected(key_events)
        else:
            raise ValueError(args[0])
Exemple #10
0
    def test_aliasing(self):
        name2code = {
            '1'     : 10,
            'exclam': 10,
        }
        self.assertListEqual(list(parse_key_combo('1 exclam', key_name_to_key_code=name2code.get)),
                             [(10, True), (10, False),
                              (10, True), (10, False)])

        for combo_string in (
            '1 ( exclam )',
            'exclam(1)',
        ):
            msg = 'parse_key_combo(%r): ValueError not raised' % (
                combo_string,
            )
            with self.assertRaisesWithMessage(ValueError, msg):
                # Yielding the first key event should
                # only happen after full validation.
                parse_key_combo(combo_string, key_name_to_key_code=name2code.get)
Exemple #11
0
    def test_aliasing(self):
        name2code = {
            '1': 10,
            'exclam': 10,
        }
        self.assertListEqual(
            list(
                parse_key_combo('1 exclam',
                                key_name_to_key_code=name2code.get)),
            [(10, True), (10, False), (10, True), (10, False)])

        for combo_string in (
                '1 ( exclam )',
                'exclam(1)',
        ):
            msg = 'parse_key_combo(%r): ValueError not raised' % (
                combo_string, )
            with self.assertRaisesWithMessage(ValueError, msg):
                # Yielding the first key event should
                # only happen after full validation.
                parse_key_combo(combo_string,
                                key_name_to_key_code=name2code.get)
Exemple #12
0
 def test_syntax_error(self):
     for combo_string in (
             # Invalid character.
             'Return,',
             'Return&',
             'Ret. urn <',
             'exclam ! foo',
             'shift[a]',
             # Unbalanced )
             ') arg',
             'arg )',
             'arg())',
             'arg(x) )',
             # Unbalanced (
             'test(',
             '( grr',
             'foo ( bar',
             'foo (bar ( ',
             'foo ((',
     ):
         msg = 'parse_key_combo(%r): SyntaxError not raised' % (
             combo_string, )
         with self.assertRaisesWithMessage(SyntaxError, msg):
             parse_key_combo(combo_string)
Exemple #13
0
 def send_key_combination(self, combo_string):
     """Emulate a sequence of key combinations.
     Argument:
     combo_string -- A string representing a sequence of key
     combinations. Keys are represented by their names in the
     self.keyboard_layout.keyname_to_keycode above. For example, the
     left Alt key is represented by 'Alt_L'. Keys are either
     separated by a space or a left or right parenthesis.
     Parentheses must be properly formed in pairs and may be
     nested. A key immediately followed by a parenthetical
     indicates that the key is pressed down while all keys enclosed
     in the parenthetical are pressed and released in turn. For
     example, Alt_L(Tab) means to hold the left Alt key down, press
     and release the Tab key, and then release the left Alt key.
     """
     # Make sure keyboard layout is up-to-date.
     self._refresh_keyboard_layout()
     # Parse and validate combo.
     key_events = parse_key_combo(combo_string, self.keyboard_layout.keyname_to_vk.get)
     # Send events...
     for keycode, pressed in key_events:
         self._key_event(keycode, pressed)
 def send_key_combination(self, combo_string):
     """Emulate a sequence of key combinations.
     Argument:
     combo_string -- A string representing a sequence of key
     combinations. Keys are represented by their names in the
     self.keyboard_layout.keyname_to_keycode above. For example, the
     left Alt key is represented by 'Alt_L'. Keys are either
     separated by a space or a left or right parenthesis.
     Parentheses must be properly formed in pairs and may be
     nested. A key immediately followed by a parenthetical
     indicates that the key is pressed down while all keys enclosed
     in the parenthetical are pressed and released in turn. For
     example, Alt_L(Tab) means to hold the left Alt key down, press
     and release the Tab key, and then release the left Alt key.
     """
     # Make sure keyboard layout is up-to-date.
     self._refresh_keyboard_layout()
     # Parse and validate combo.
     key_events = parse_key_combo(combo_string, self.keyboard_layout.keyname_to_vk.get)
     # Send events...
     for keycode, pressed in key_events:
         self._key_event(keycode, pressed)
Exemple #15
0
    def send_key_combination(self, combo_string):
        """Emulate a sequence of key combinations.

        Args:
            combo_string: A string representing a sequence of key
                combinations. Keys are represented by their names in the
                Xlib.XK module, without the 'XK_' prefix. For example, the
                left Alt key is represented by 'Alt_L'. Keys are either
                separated by a space or a left or right parenthesis.
                Parentheses must be properly formed in pairs and may be
                nested. A key immediately followed by a parenthetical
                indicates that the key is pressed down while all keys enclosed
                in the parenthetical are pressed and released in turn. For
                example, Alt_L(Tab) means to hold the left Alt key down, press
                and release the Tab key, and then release the left Alt key.

        """
        def name_to_code(name):
            # Static key codes
            code = KEYNAME_TO_KEYCODE.get(name)
            if code is not None:
                pass
            # Dead keys
            elif name.startswith('dead_'):
                code, mod = self._layout.deadkey_symbol_to_key_sequence(
                    DEADKEY_SYMBOLS.get(name)
                )[0]
            # Normal keys
            else:
                char = KEYNAME_TO_CHAR.get(name, name)
                code, mods = self._layout.char_to_key_sequence(char)[0]
            return code
        # Parse and validate combo.
        key_events = parse_key_combo(combo_string, name_to_code)
        # Send events...
        self._send_sequence(key_events)
Exemple #16
0
 def test_noop(self):
     for combo_string in ('', '   '):
         self.assertEqual(parse_key_combo(combo_string), [])
Exemple #17
0
 def test_bad_keyname(self):
     name2code = {c: c for c in '123abc'}
     combo_string = '1 (c) 2 bad 3 (a b c)'
     msg = 'parse_key_combo(%r): ValueError not raised' % (combo_string, )
     with self.assertRaisesWithMessage(ValueError, msg):
         parse_key_combo(combo_string, key_name_to_key_code=name2code.get)
Exemple #18
0
 def test_noop(self):
     for combo_string in ('', '   '):
         self.assertEqual(parse_key_combo(combo_string), [])