Files
tinypilot-kvm/app/text_to_hid_test.py
Jason Wallace 3a7fe4ac65 Port text to HID keystroke logic (#1624)
Related https://github.com/tiny-pilot/tinypilot/issues/1026

This PR ports TinyPilot's "paste" functionality from the fontend to the
backend, by parsing the pasted text into HID keystrokes on the server.

This PR copies the functionality of the following JS files to Python
files, without modifying any existing code:
*
[`app/static/js/keycodes.js`](3de1916aa5/app/static/js/keycodes.js)
->
[`app/text_to_hid.py`](3de1916aa5/app/text_to_hid.py)
*
[`app/static/js/keycodes.test.js`](3de1916aa5/app/static/js/keycodes.test.js)
->
[`app/text_to_hid_test.py`](3de1916aa5/app/text_to_hid_test.py)

### Notes
1. I've changed the way that we determine if a text character (e.g.,
`A`) requires a key modifier (e.g., left shift) when being typed on a
keyboard. Instead of [all keyboard languages matching against a single
regex](3de1916aa5/app/static/js/keycodes.js (L102-L106)),
we now map a [text character on a specific language keyboard directly to
a HID
keystroke](3de1916aa5/app/text_to_hid.py (L132-L133)).
This should allow us to avoid ambiguity between keyboard languages and
support more text characters.

### Peer testing
You can test this PR on device via the following stacked PR:
* https://github.com/tiny-pilot/tinypilot/pull/1626

<a data-ca-tag
href="https://codeapprove.com/pr/tiny-pilot/tinypilot/1624"><img
src="https://codeapprove.com/external/github-tag-allbg.png" alt="Review
on CodeApprove" /></a>
2023-09-19 12:56:00 +02:00

38 lines
1.3 KiB
Python

import unittest
import text_to_hid
from hid import keycodes as hid
class ConvertTextToHidTest(unittest.TestCase):
def test_keystroke_without_modifier(self):
self.assertEqual(hid.Keystroke(keycode=hid.KEYCODE_A),
text_to_hid.convert('a', 'en-US'))
def test_keystroke_with_modifier(self):
self.assertEqual(
hid.Keystroke(keycode=hid.KEYCODE_A,
modifier=hid.MODIFIER_LEFT_SHIFT),
text_to_hid.convert('A', 'en-US'))
def test_language_mapping(self):
self.assertEqual(
hid.Keystroke(hid.KEYCODE_NUMBER_2, hid.MODIFIER_LEFT_SHIFT),
text_to_hid.convert('@', 'en-US'))
self.assertEqual(
hid.Keystroke(hid.KEYCODE_SINGLE_QUOTE, hid.MODIFIER_LEFT_SHIFT),
text_to_hid.convert('@', 'en-GB'))
def test_defaults_to_us_english_language_mapping(self):
self.assertEqual(
hid.Keystroke(hid.KEYCODE_NUMBER_2, hid.MODIFIER_LEFT_SHIFT),
text_to_hid.convert('@', 'fake-language'))
def test_raises_error_on_unsupported_character(self):
with self.assertRaises(text_to_hid.UnsupportedCharacterError):
text_to_hid.convert('\a', 'en-US')
def test_ignored_character(self):
self.assertEqual(None, text_to_hid.convert('\r', 'en-US'))