1a46c0ec8Sopenharmony_ci#!/usr/bin/env python3 2a46c0ec8Sopenharmony_ci# vim: set expandtab shiftwidth=4: 3a46c0ec8Sopenharmony_ci# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */ 4a46c0ec8Sopenharmony_ci# 5a46c0ec8Sopenharmony_ci# Copyright © 2018 Red Hat, Inc. 6a46c0ec8Sopenharmony_ci# 7a46c0ec8Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 8a46c0ec8Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 9a46c0ec8Sopenharmony_ci# to deal in the Software without restriction, including without limitation 10a46c0ec8Sopenharmony_ci# the rights to use, copy, modify, merge, publish, distribute, sublicense, 11a46c0ec8Sopenharmony_ci# and/or sell copies of the Software, and to permit persons to whom the 12a46c0ec8Sopenharmony_ci# Software is furnished to do so, subject to the following conditions: 13a46c0ec8Sopenharmony_ci# 14a46c0ec8Sopenharmony_ci# The above copyright notice and this permission notice (including the next 15a46c0ec8Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 16a46c0ec8Sopenharmony_ci# Software. 17a46c0ec8Sopenharmony_ci# 18a46c0ec8Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19a46c0ec8Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20a46c0ec8Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21a46c0ec8Sopenharmony_ci# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22a46c0ec8Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23a46c0ec8Sopenharmony_ci# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24a46c0ec8Sopenharmony_ci# DEALINGS IN THE SOFTWARE. 25a46c0ec8Sopenharmony_ci 26a46c0ec8Sopenharmony_ciimport argparse 27a46c0ec8Sopenharmony_ciimport os 28a46c0ec8Sopenharmony_ciimport sys 29a46c0ec8Sopenharmony_ciimport unittest 30a46c0ec8Sopenharmony_ciimport yaml 31a46c0ec8Sopenharmony_ciimport re 32a46c0ec8Sopenharmony_ci 33a46c0ec8Sopenharmony_cifrom pkg_resources import parse_version 34a46c0ec8Sopenharmony_ci 35a46c0ec8Sopenharmony_ci 36a46c0ec8Sopenharmony_ciclass TestYaml(unittest.TestCase): 37a46c0ec8Sopenharmony_ci filename = "" 38a46c0ec8Sopenharmony_ci 39a46c0ec8Sopenharmony_ci @classmethod 40a46c0ec8Sopenharmony_ci def setUpClass(cls): 41a46c0ec8Sopenharmony_ci with open(cls.filename) as f: 42a46c0ec8Sopenharmony_ci cls.yaml = yaml.safe_load(f) 43a46c0ec8Sopenharmony_ci 44a46c0ec8Sopenharmony_ci def dict_key_crosscheck(self, d, keys): 45a46c0ec8Sopenharmony_ci """Check that each key in d is in keys, and that each key is in d""" 46a46c0ec8Sopenharmony_ci self.assertEqual(sorted(d.keys()), sorted(keys)) 47a46c0ec8Sopenharmony_ci 48a46c0ec8Sopenharmony_ci def libinput_events(self, filter=None): 49a46c0ec8Sopenharmony_ci """Returns all libinput events in the recording, regardless of the 50a46c0ec8Sopenharmony_ci device""" 51a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 52a46c0ec8Sopenharmony_ci for d in devices: 53a46c0ec8Sopenharmony_ci events = d["events"] 54a46c0ec8Sopenharmony_ci if not events: 55a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 56a46c0ec8Sopenharmony_ci for e in events: 57a46c0ec8Sopenharmony_ci try: 58a46c0ec8Sopenharmony_ci libinput = e["libinput"] 59a46c0ec8Sopenharmony_ci except KeyError: 60a46c0ec8Sopenharmony_ci continue 61a46c0ec8Sopenharmony_ci 62a46c0ec8Sopenharmony_ci for ev in libinput: 63a46c0ec8Sopenharmony_ci if ( 64a46c0ec8Sopenharmony_ci filter is None 65a46c0ec8Sopenharmony_ci or ev["type"] == filter 66a46c0ec8Sopenharmony_ci or isinstance(filter, list) 67a46c0ec8Sopenharmony_ci and ev["type"] in filter 68a46c0ec8Sopenharmony_ci ): 69a46c0ec8Sopenharmony_ci yield ev 70a46c0ec8Sopenharmony_ci 71a46c0ec8Sopenharmony_ci def test_sections_exist(self): 72a46c0ec8Sopenharmony_ci sections = ["version", "ndevices", "libinput", "system", "devices"] 73a46c0ec8Sopenharmony_ci for section in sections: 74a46c0ec8Sopenharmony_ci self.assertIn(section, self.yaml) 75a46c0ec8Sopenharmony_ci 76a46c0ec8Sopenharmony_ci def test_version(self): 77a46c0ec8Sopenharmony_ci version = self.yaml["version"] 78a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(version, int)) 79a46c0ec8Sopenharmony_ci self.assertEqual(version, 1) 80a46c0ec8Sopenharmony_ci 81a46c0ec8Sopenharmony_ci def test_ndevices(self): 82a46c0ec8Sopenharmony_ci ndevices = self.yaml["ndevices"] 83a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(ndevices, int)) 84a46c0ec8Sopenharmony_ci self.assertGreaterEqual(ndevices, 1) 85a46c0ec8Sopenharmony_ci self.assertEqual(ndevices, len(self.yaml["devices"])) 86a46c0ec8Sopenharmony_ci 87a46c0ec8Sopenharmony_ci def test_libinput(self): 88a46c0ec8Sopenharmony_ci libinput = self.yaml["libinput"] 89a46c0ec8Sopenharmony_ci version = libinput["version"] 90a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(version, str)) 91a46c0ec8Sopenharmony_ci self.assertGreaterEqual(parse_version(version), parse_version("1.10.0")) 92a46c0ec8Sopenharmony_ci git = libinput["git"] 93a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(git, str)) 94a46c0ec8Sopenharmony_ci self.assertNotEqual(git, "unknown") 95a46c0ec8Sopenharmony_ci 96a46c0ec8Sopenharmony_ci def test_system(self): 97a46c0ec8Sopenharmony_ci system = self.yaml["system"] 98a46c0ec8Sopenharmony_ci kernel = system["kernel"] 99a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(kernel, str)) 100a46c0ec8Sopenharmony_ci self.assertEqual(kernel, os.uname().release) 101a46c0ec8Sopenharmony_ci 102a46c0ec8Sopenharmony_ci dmi = system["dmi"] 103a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(dmi, str)) 104a46c0ec8Sopenharmony_ci with open("/sys/class/dmi/id/modalias") as f: 105a46c0ec8Sopenharmony_ci sys_dmi = f.read()[:-1] # trailing newline 106a46c0ec8Sopenharmony_ci self.assertEqual(dmi, sys_dmi) 107a46c0ec8Sopenharmony_ci 108a46c0ec8Sopenharmony_ci def test_devices_sections_exist(self): 109a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 110a46c0ec8Sopenharmony_ci for d in devices: 111a46c0ec8Sopenharmony_ci self.assertIn("node", d) 112a46c0ec8Sopenharmony_ci self.assertIn("evdev", d) 113a46c0ec8Sopenharmony_ci self.assertIn("udev", d) 114a46c0ec8Sopenharmony_ci 115a46c0ec8Sopenharmony_ci def test_evdev_sections_exist(self): 116a46c0ec8Sopenharmony_ci sections = ["name", "id", "codes", "properties"] 117a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 118a46c0ec8Sopenharmony_ci for d in devices: 119a46c0ec8Sopenharmony_ci evdev = d["evdev"] 120a46c0ec8Sopenharmony_ci for s in sections: 121a46c0ec8Sopenharmony_ci self.assertIn(s, evdev) 122a46c0ec8Sopenharmony_ci 123a46c0ec8Sopenharmony_ci def test_evdev_name(self): 124a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 125a46c0ec8Sopenharmony_ci for d in devices: 126a46c0ec8Sopenharmony_ci evdev = d["evdev"] 127a46c0ec8Sopenharmony_ci name = evdev["name"] 128a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(name, str)) 129a46c0ec8Sopenharmony_ci self.assertGreaterEqual(len(name), 5) 130a46c0ec8Sopenharmony_ci 131a46c0ec8Sopenharmony_ci def test_evdev_id(self): 132a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 133a46c0ec8Sopenharmony_ci for d in devices: 134a46c0ec8Sopenharmony_ci evdev = d["evdev"] 135a46c0ec8Sopenharmony_ci id = evdev["id"] 136a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(id, list)) 137a46c0ec8Sopenharmony_ci self.assertEqual(len(id), 4) 138a46c0ec8Sopenharmony_ci self.assertGreater(id[0], 0) 139a46c0ec8Sopenharmony_ci self.assertGreater(id[1], 0) 140a46c0ec8Sopenharmony_ci 141a46c0ec8Sopenharmony_ci def test_evdev_properties(self): 142a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 143a46c0ec8Sopenharmony_ci for d in devices: 144a46c0ec8Sopenharmony_ci evdev = d["evdev"] 145a46c0ec8Sopenharmony_ci properties = evdev["properties"] 146a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(properties, list)) 147a46c0ec8Sopenharmony_ci 148a46c0ec8Sopenharmony_ci def test_hid(self): 149a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 150a46c0ec8Sopenharmony_ci for d in devices: 151a46c0ec8Sopenharmony_ci hid = d["hid"] 152a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(hid, list)) 153a46c0ec8Sopenharmony_ci for byte in hid: 154a46c0ec8Sopenharmony_ci self.assertGreaterEqual(byte, 0) 155a46c0ec8Sopenharmony_ci self.assertLessEqual(byte, 255) 156a46c0ec8Sopenharmony_ci 157a46c0ec8Sopenharmony_ci def test_udev_sections_exist(self): 158a46c0ec8Sopenharmony_ci sections = ["properties"] 159a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 160a46c0ec8Sopenharmony_ci for d in devices: 161a46c0ec8Sopenharmony_ci udev = d["udev"] 162a46c0ec8Sopenharmony_ci for s in sections: 163a46c0ec8Sopenharmony_ci self.assertIn(s, udev) 164a46c0ec8Sopenharmony_ci 165a46c0ec8Sopenharmony_ci def test_udev_properties(self): 166a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 167a46c0ec8Sopenharmony_ci for d in devices: 168a46c0ec8Sopenharmony_ci udev = d["udev"] 169a46c0ec8Sopenharmony_ci properties = udev["properties"] 170a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(properties, list)) 171a46c0ec8Sopenharmony_ci self.assertGreater(len(properties), 0) 172a46c0ec8Sopenharmony_ci 173a46c0ec8Sopenharmony_ci self.assertIn("ID_INPUT=1", properties) 174a46c0ec8Sopenharmony_ci for p in properties: 175a46c0ec8Sopenharmony_ci self.assertTrue(re.match("[A-Z0-9_]+=.+", p)) 176a46c0ec8Sopenharmony_ci 177a46c0ec8Sopenharmony_ci def test_udev_id_inputs(self): 178a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 179a46c0ec8Sopenharmony_ci for d in devices: 180a46c0ec8Sopenharmony_ci udev = d["udev"] 181a46c0ec8Sopenharmony_ci properties = udev["properties"] 182a46c0ec8Sopenharmony_ci id_inputs = [p for p in properties if p.startswith("ID_INPUT")] 183a46c0ec8Sopenharmony_ci # We expect ID_INPUT and ID_INPUT_something, but might get more 184a46c0ec8Sopenharmony_ci # than one of the latter 185a46c0ec8Sopenharmony_ci self.assertGreaterEqual(len(id_inputs), 2) 186a46c0ec8Sopenharmony_ci 187a46c0ec8Sopenharmony_ci def test_events_have_section(self): 188a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 189a46c0ec8Sopenharmony_ci for d in devices: 190a46c0ec8Sopenharmony_ci events = d["events"] 191a46c0ec8Sopenharmony_ci if not events: 192a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 193a46c0ec8Sopenharmony_ci for e in events: 194a46c0ec8Sopenharmony_ci self.assertTrue("evdev" in e or "libinput" in e) 195a46c0ec8Sopenharmony_ci 196a46c0ec8Sopenharmony_ci def test_events_evdev(self): 197a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 198a46c0ec8Sopenharmony_ci for d in devices: 199a46c0ec8Sopenharmony_ci events = d["events"] 200a46c0ec8Sopenharmony_ci if not events: 201a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 202a46c0ec8Sopenharmony_ci for e in events: 203a46c0ec8Sopenharmony_ci try: 204a46c0ec8Sopenharmony_ci evdev = e["evdev"] 205a46c0ec8Sopenharmony_ci except KeyError: 206a46c0ec8Sopenharmony_ci continue 207a46c0ec8Sopenharmony_ci 208a46c0ec8Sopenharmony_ci for ev in evdev: 209a46c0ec8Sopenharmony_ci self.assertEqual(len(ev), 5) 210a46c0ec8Sopenharmony_ci 211a46c0ec8Sopenharmony_ci # Last event in each frame is SYN_REPORT 212a46c0ec8Sopenharmony_ci ev_syn = evdev[-1] 213a46c0ec8Sopenharmony_ci self.assertEqual(ev_syn[2], 0) 214a46c0ec8Sopenharmony_ci self.assertEqual(ev_syn[3], 0) 215a46c0ec8Sopenharmony_ci # SYN_REPORT value is 1 in case of some key repeats 216a46c0ec8Sopenharmony_ci self.assertLessEqual(ev_syn[4], 1) 217a46c0ec8Sopenharmony_ci 218a46c0ec8Sopenharmony_ci def test_events_evdev_syn_report(self): 219a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 220a46c0ec8Sopenharmony_ci for d in devices: 221a46c0ec8Sopenharmony_ci events = d["events"] 222a46c0ec8Sopenharmony_ci if not events: 223a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 224a46c0ec8Sopenharmony_ci for e in events: 225a46c0ec8Sopenharmony_ci try: 226a46c0ec8Sopenharmony_ci evdev = e["evdev"] 227a46c0ec8Sopenharmony_ci except KeyError: 228a46c0ec8Sopenharmony_ci continue 229a46c0ec8Sopenharmony_ci for ev in evdev[:-1]: 230a46c0ec8Sopenharmony_ci self.assertFalse(ev[2] == 0 and ev[3] == 0) 231a46c0ec8Sopenharmony_ci 232a46c0ec8Sopenharmony_ci def test_events_libinput(self): 233a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 234a46c0ec8Sopenharmony_ci for d in devices: 235a46c0ec8Sopenharmony_ci events = d["events"] 236a46c0ec8Sopenharmony_ci if not events: 237a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 238a46c0ec8Sopenharmony_ci for e in events: 239a46c0ec8Sopenharmony_ci try: 240a46c0ec8Sopenharmony_ci libinput = e["libinput"] 241a46c0ec8Sopenharmony_ci except KeyError: 242a46c0ec8Sopenharmony_ci continue 243a46c0ec8Sopenharmony_ci 244a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(libinput, list)) 245a46c0ec8Sopenharmony_ci for ev in libinput: 246a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(ev, dict)) 247a46c0ec8Sopenharmony_ci 248a46c0ec8Sopenharmony_ci def test_events_libinput_type(self): 249a46c0ec8Sopenharmony_ci types = [ 250a46c0ec8Sopenharmony_ci "POINTER_MOTION", 251a46c0ec8Sopenharmony_ci "POINTER_MOTION_ABSOLUTE", 252a46c0ec8Sopenharmony_ci "POINTER_AXIS", 253a46c0ec8Sopenharmony_ci "POINTER_BUTTON", 254a46c0ec8Sopenharmony_ci "DEVICE_ADDED", 255a46c0ec8Sopenharmony_ci "KEYBOARD_KEY", 256a46c0ec8Sopenharmony_ci "TOUCH_DOWN", 257a46c0ec8Sopenharmony_ci "TOUCH_MOTION", 258a46c0ec8Sopenharmony_ci "TOUCH_UP", 259a46c0ec8Sopenharmony_ci "TOUCH_FRAME", 260a46c0ec8Sopenharmony_ci "GESTURE_SWIPE_BEGIN", 261a46c0ec8Sopenharmony_ci "GESTURE_SWIPE_UPDATE", 262a46c0ec8Sopenharmony_ci "GESTURE_SWIPE_END", 263a46c0ec8Sopenharmony_ci "GESTURE_PINCH_BEGIN", 264a46c0ec8Sopenharmony_ci "GESTURE_PINCH_UPDATE", 265a46c0ec8Sopenharmony_ci "GESTURE_PINCH_END", 266a46c0ec8Sopenharmony_ci "TABLET_TOOL_AXIS", 267a46c0ec8Sopenharmony_ci "TABLET_TOOL_PROXIMITY", 268a46c0ec8Sopenharmony_ci "TABLET_TOOL_BUTTON", 269a46c0ec8Sopenharmony_ci "TABLET_TOOL_TIP", 270a46c0ec8Sopenharmony_ci "TABLET_PAD_STRIP", 271a46c0ec8Sopenharmony_ci "TABLET_PAD_RING", 272a46c0ec8Sopenharmony_ci "TABLET_PAD_BUTTON", 273a46c0ec8Sopenharmony_ci "SWITCH_TOGGLE", 274a46c0ec8Sopenharmony_ci ] 275a46c0ec8Sopenharmony_ci for e in self.libinput_events(): 276a46c0ec8Sopenharmony_ci self.assertIn("type", e) 277a46c0ec8Sopenharmony_ci self.assertIn(e["type"], types) 278a46c0ec8Sopenharmony_ci 279a46c0ec8Sopenharmony_ci def test_events_libinput_time(self): 280a46c0ec8Sopenharmony_ci # DEVICE_ADDED has no time 281a46c0ec8Sopenharmony_ci # first event may have 0.0 time if the first frame generates a 282a46c0ec8Sopenharmony_ci # libinput event. 283a46c0ec8Sopenharmony_ci try: 284a46c0ec8Sopenharmony_ci for e in list(self.libinput_events())[2:]: 285a46c0ec8Sopenharmony_ci self.assertIn("time", e) 286a46c0ec8Sopenharmony_ci self.assertGreater(e["time"], 0.0) 287a46c0ec8Sopenharmony_ci self.assertLess(e["time"], 60.0) 288a46c0ec8Sopenharmony_ci except IndexError: 289a46c0ec8Sopenharmony_ci pass 290a46c0ec8Sopenharmony_ci 291a46c0ec8Sopenharmony_ci def test_events_libinput_device_added(self): 292a46c0ec8Sopenharmony_ci keys = ["type", "seat", "logical_seat"] 293a46c0ec8Sopenharmony_ci for e in self.libinput_events("DEVICE_ADDED"): 294a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 295a46c0ec8Sopenharmony_ci self.assertEqual(e["seat"], "seat0") 296a46c0ec8Sopenharmony_ci self.assertEqual(e["logical_seat"], "default") 297a46c0ec8Sopenharmony_ci 298a46c0ec8Sopenharmony_ci def test_events_libinput_pointer_motion(self): 299a46c0ec8Sopenharmony_ci keys = ["type", "time", "delta", "unaccel"] 300a46c0ec8Sopenharmony_ci for e in self.libinput_events("POINTER_MOTION"): 301a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 302a46c0ec8Sopenharmony_ci delta = e["delta"] 303a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(delta, list)) 304a46c0ec8Sopenharmony_ci self.assertEqual(len(delta), 2) 305a46c0ec8Sopenharmony_ci for d in delta: 306a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 307a46c0ec8Sopenharmony_ci unaccel = e["unaccel"] 308a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(unaccel, list)) 309a46c0ec8Sopenharmony_ci self.assertEqual(len(unaccel), 2) 310a46c0ec8Sopenharmony_ci for d in unaccel: 311a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 312a46c0ec8Sopenharmony_ci 313a46c0ec8Sopenharmony_ci def test_events_libinput_pointer_button(self): 314a46c0ec8Sopenharmony_ci keys = ["type", "time", "button", "state", "seat_count"] 315a46c0ec8Sopenharmony_ci for e in self.libinput_events("POINTER_BUTTON"): 316a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 317a46c0ec8Sopenharmony_ci button = e["button"] 318a46c0ec8Sopenharmony_ci self.assertGreater(button, 0x100) # BTN_0 319a46c0ec8Sopenharmony_ci self.assertLess(button, 0x160) # KEY_OK 320a46c0ec8Sopenharmony_ci state = e["state"] 321a46c0ec8Sopenharmony_ci self.assertIn(state, ["pressed", "released"]) 322a46c0ec8Sopenharmony_ci scount = e["seat_count"] 323a46c0ec8Sopenharmony_ci self.assertGreaterEqual(scount, 0) 324a46c0ec8Sopenharmony_ci 325a46c0ec8Sopenharmony_ci def test_events_libinput_pointer_absolute(self): 326a46c0ec8Sopenharmony_ci keys = ["type", "time", "point", "transformed"] 327a46c0ec8Sopenharmony_ci for e in self.libinput_events("POINTER_MOTION_ABSOLUTE"): 328a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 329a46c0ec8Sopenharmony_ci point = e["point"] 330a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(point, list)) 331a46c0ec8Sopenharmony_ci self.assertEqual(len(point), 2) 332a46c0ec8Sopenharmony_ci for p in point: 333a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 334a46c0ec8Sopenharmony_ci self.assertGreater(p, 0.0) 335a46c0ec8Sopenharmony_ci self.assertLess(p, 300.0) 336a46c0ec8Sopenharmony_ci 337a46c0ec8Sopenharmony_ci transformed = e["transformed"] 338a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(transformed, list)) 339a46c0ec8Sopenharmony_ci self.assertEqual(len(transformed), 2) 340a46c0ec8Sopenharmony_ci for t in transformed: 341a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(t, float)) 342a46c0ec8Sopenharmony_ci self.assertGreater(t, 0.0) 343a46c0ec8Sopenharmony_ci self.assertLess(t, 100.0) 344a46c0ec8Sopenharmony_ci 345a46c0ec8Sopenharmony_ci def test_events_libinput_touch(self): 346a46c0ec8Sopenharmony_ci keys = ["type", "time", "slot", "seat_slot"] 347a46c0ec8Sopenharmony_ci for e in self.libinput_events(): 348a46c0ec8Sopenharmony_ci if not e["type"].startswith("TOUCH_") or e["type"] == "TOUCH_FRAME": 349a46c0ec8Sopenharmony_ci continue 350a46c0ec8Sopenharmony_ci 351a46c0ec8Sopenharmony_ci for k in keys: 352a46c0ec8Sopenharmony_ci self.assertIn(k, e.keys()) 353a46c0ec8Sopenharmony_ci slot = e["slot"] 354a46c0ec8Sopenharmony_ci seat_slot = e["seat_slot"] 355a46c0ec8Sopenharmony_ci 356a46c0ec8Sopenharmony_ci self.assertGreaterEqual(slot, 0) 357a46c0ec8Sopenharmony_ci self.assertGreaterEqual(seat_slot, 0) 358a46c0ec8Sopenharmony_ci 359a46c0ec8Sopenharmony_ci def test_events_libinput_touch_down(self): 360a46c0ec8Sopenharmony_ci keys = ["type", "time", "slot", "seat_slot", "point", "transformed"] 361a46c0ec8Sopenharmony_ci for e in self.libinput_events("TOUCH_DOWN"): 362a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 363a46c0ec8Sopenharmony_ci point = e["point"] 364a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(point, list)) 365a46c0ec8Sopenharmony_ci self.assertEqual(len(point), 2) 366a46c0ec8Sopenharmony_ci for p in point: 367a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 368a46c0ec8Sopenharmony_ci self.assertGreater(p, 0.0) 369a46c0ec8Sopenharmony_ci self.assertLess(p, 300.0) 370a46c0ec8Sopenharmony_ci 371a46c0ec8Sopenharmony_ci transformed = e["transformed"] 372a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(transformed, list)) 373a46c0ec8Sopenharmony_ci self.assertEqual(len(transformed), 2) 374a46c0ec8Sopenharmony_ci for t in transformed: 375a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(t, float)) 376a46c0ec8Sopenharmony_ci self.assertGreater(t, 0.0) 377a46c0ec8Sopenharmony_ci self.assertLess(t, 100.0) 378a46c0ec8Sopenharmony_ci 379a46c0ec8Sopenharmony_ci def test_events_libinput_touch_motion(self): 380a46c0ec8Sopenharmony_ci keys = ["type", "time", "slot", "seat_slot", "point", "transformed"] 381a46c0ec8Sopenharmony_ci for e in self.libinput_events("TOUCH_MOTION"): 382a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 383a46c0ec8Sopenharmony_ci point = e["point"] 384a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(point, list)) 385a46c0ec8Sopenharmony_ci self.assertEqual(len(point), 2) 386a46c0ec8Sopenharmony_ci for p in point: 387a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 388a46c0ec8Sopenharmony_ci self.assertGreater(p, 0.0) 389a46c0ec8Sopenharmony_ci self.assertLess(p, 300.0) 390a46c0ec8Sopenharmony_ci 391a46c0ec8Sopenharmony_ci transformed = e["transformed"] 392a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(transformed, list)) 393a46c0ec8Sopenharmony_ci self.assertEqual(len(transformed), 2) 394a46c0ec8Sopenharmony_ci for t in transformed: 395a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(t, float)) 396a46c0ec8Sopenharmony_ci self.assertGreater(t, 0.0) 397a46c0ec8Sopenharmony_ci self.assertLess(t, 100.0) 398a46c0ec8Sopenharmony_ci 399a46c0ec8Sopenharmony_ci def test_events_libinput_touch_frame(self): 400a46c0ec8Sopenharmony_ci devices = self.yaml["devices"] 401a46c0ec8Sopenharmony_ci for d in devices: 402a46c0ec8Sopenharmony_ci events = d["events"] 403a46c0ec8Sopenharmony_ci if not events: 404a46c0ec8Sopenharmony_ci raise unittest.SkipTest() 405a46c0ec8Sopenharmony_ci for e in events: 406a46c0ec8Sopenharmony_ci try: 407a46c0ec8Sopenharmony_ci evdev = e["libinput"] 408a46c0ec8Sopenharmony_ci except KeyError: 409a46c0ec8Sopenharmony_ci continue 410a46c0ec8Sopenharmony_ci 411a46c0ec8Sopenharmony_ci need_frame = False 412a46c0ec8Sopenharmony_ci for ev in evdev: 413a46c0ec8Sopenharmony_ci t = ev["type"] 414a46c0ec8Sopenharmony_ci if not t.startswith("TOUCH_"): 415a46c0ec8Sopenharmony_ci self.assertFalse(need_frame) 416a46c0ec8Sopenharmony_ci continue 417a46c0ec8Sopenharmony_ci 418a46c0ec8Sopenharmony_ci if t == "TOUCH_FRAME": 419a46c0ec8Sopenharmony_ci self.assertTrue(need_frame) 420a46c0ec8Sopenharmony_ci need_frame = False 421a46c0ec8Sopenharmony_ci else: 422a46c0ec8Sopenharmony_ci need_frame = True 423a46c0ec8Sopenharmony_ci 424a46c0ec8Sopenharmony_ci self.assertFalse(need_frame) 425a46c0ec8Sopenharmony_ci 426a46c0ec8Sopenharmony_ci def test_events_libinput_gesture_pinch(self): 427a46c0ec8Sopenharmony_ci keys = ["type", "time", "nfingers", "delta", "unaccel", "angle_delta", "scale"] 428a46c0ec8Sopenharmony_ci for e in self.libinput_events( 429a46c0ec8Sopenharmony_ci ["GESTURE_PINCH_BEGIN", "GESTURE_PINCH_UPDATE", "GESTURE_PINCH_END"] 430a46c0ec8Sopenharmony_ci ): 431a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 432a46c0ec8Sopenharmony_ci delta = e["delta"] 433a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(delta, list)) 434a46c0ec8Sopenharmony_ci self.assertEqual(len(delta), 2) 435a46c0ec8Sopenharmony_ci for d in delta: 436a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 437a46c0ec8Sopenharmony_ci unaccel = e["unaccel"] 438a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(unaccel, list)) 439a46c0ec8Sopenharmony_ci self.assertEqual(len(unaccel), 2) 440a46c0ec8Sopenharmony_ci for d in unaccel: 441a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 442a46c0ec8Sopenharmony_ci 443a46c0ec8Sopenharmony_ci adelta = e["angle_delta"] 444a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(adelta, list)) 445a46c0ec8Sopenharmony_ci self.assertEqual(len(adelta), 2) 446a46c0ec8Sopenharmony_ci for d in adelta: 447a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 448a46c0ec8Sopenharmony_ci 449a46c0ec8Sopenharmony_ci scale = e["scale"] 450a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(scale, list)) 451a46c0ec8Sopenharmony_ci self.assertEqual(len(scale), 2) 452a46c0ec8Sopenharmony_ci for d in scale: 453a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 454a46c0ec8Sopenharmony_ci 455a46c0ec8Sopenharmony_ci def test_events_libinput_gesture_swipe(self): 456a46c0ec8Sopenharmony_ci keys = ["type", "time", "nfingers", "delta", "unaccel"] 457a46c0ec8Sopenharmony_ci for e in self.libinput_events( 458a46c0ec8Sopenharmony_ci ["GESTURE_SWIPE_BEGIN", "GESTURE_SWIPE_UPDATE", "GESTURE_SWIPE_END"] 459a46c0ec8Sopenharmony_ci ): 460a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 461a46c0ec8Sopenharmony_ci delta = e["delta"] 462a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(delta, list)) 463a46c0ec8Sopenharmony_ci self.assertEqual(len(delta), 2) 464a46c0ec8Sopenharmony_ci for d in delta: 465a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 466a46c0ec8Sopenharmony_ci unaccel = e["unaccel"] 467a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(unaccel, list)) 468a46c0ec8Sopenharmony_ci self.assertEqual(len(unaccel), 2) 469a46c0ec8Sopenharmony_ci for d in unaccel: 470a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 471a46c0ec8Sopenharmony_ci 472a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_pad_button(self): 473a46c0ec8Sopenharmony_ci keys = ["type", "time", "button", "state", "mode", "is-toggle"] 474a46c0ec8Sopenharmony_ci 475a46c0ec8Sopenharmony_ci for e in self.libinput_events("TABLET_PAD_BUTTON"): 476a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 477a46c0ec8Sopenharmony_ci 478a46c0ec8Sopenharmony_ci b = e["button"] 479a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(b, int)) 480a46c0ec8Sopenharmony_ci self.assertGreaterEqual(b, 0) 481a46c0ec8Sopenharmony_ci self.assertLessEqual(b, 16) 482a46c0ec8Sopenharmony_ci 483a46c0ec8Sopenharmony_ci state = e["state"] 484a46c0ec8Sopenharmony_ci self.assertIn(state, ["pressed", "released"]) 485a46c0ec8Sopenharmony_ci 486a46c0ec8Sopenharmony_ci m = e["mode"] 487a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(m, int)) 488a46c0ec8Sopenharmony_ci self.assertGreaterEqual(m, 0) 489a46c0ec8Sopenharmony_ci self.assertLessEqual(m, 3) 490a46c0ec8Sopenharmony_ci 491a46c0ec8Sopenharmony_ci t = e["is-toggle"] 492a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(t, bool)) 493a46c0ec8Sopenharmony_ci 494a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_pad_ring(self): 495a46c0ec8Sopenharmony_ci keys = ["type", "time", "number", "position", "source", "mode"] 496a46c0ec8Sopenharmony_ci 497a46c0ec8Sopenharmony_ci for e in self.libinput_events("TABLET_PAD_RING"): 498a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 499a46c0ec8Sopenharmony_ci 500a46c0ec8Sopenharmony_ci n = e["number"] 501a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(n, int)) 502a46c0ec8Sopenharmony_ci self.assertGreaterEqual(n, 0) 503a46c0ec8Sopenharmony_ci self.assertLessEqual(n, 4) 504a46c0ec8Sopenharmony_ci 505a46c0ec8Sopenharmony_ci p = e["position"] 506a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 507a46c0ec8Sopenharmony_ci if p != -1.0: # special 'end' case 508a46c0ec8Sopenharmony_ci self.assertGreaterEqual(p, 0.0) 509a46c0ec8Sopenharmony_ci self.assertLess(p, 360.0) 510a46c0ec8Sopenharmony_ci 511a46c0ec8Sopenharmony_ci m = e["mode"] 512a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(m, int)) 513a46c0ec8Sopenharmony_ci self.assertGreaterEqual(m, 0) 514a46c0ec8Sopenharmony_ci self.assertLessEqual(m, 3) 515a46c0ec8Sopenharmony_ci 516a46c0ec8Sopenharmony_ci s = e["source"] 517a46c0ec8Sopenharmony_ci self.assertIn(s, ["finger", "unknown"]) 518a46c0ec8Sopenharmony_ci 519a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_pad_strip(self): 520a46c0ec8Sopenharmony_ci keys = ["type", "time", "number", "position", "source", "mode"] 521a46c0ec8Sopenharmony_ci 522a46c0ec8Sopenharmony_ci for e in self.libinput_events("TABLET_PAD_STRIP"): 523a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 524a46c0ec8Sopenharmony_ci 525a46c0ec8Sopenharmony_ci n = e["number"] 526a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(n, int)) 527a46c0ec8Sopenharmony_ci self.assertGreaterEqual(n, 0) 528a46c0ec8Sopenharmony_ci self.assertLessEqual(n, 4) 529a46c0ec8Sopenharmony_ci 530a46c0ec8Sopenharmony_ci p = e["position"] 531a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 532a46c0ec8Sopenharmony_ci if p != -1.0: # special 'end' case 533a46c0ec8Sopenharmony_ci self.assertGreaterEqual(p, 0.0) 534a46c0ec8Sopenharmony_ci self.assertLessEqual(p, 1.0) 535a46c0ec8Sopenharmony_ci 536a46c0ec8Sopenharmony_ci m = e["mode"] 537a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(m, int)) 538a46c0ec8Sopenharmony_ci self.assertGreaterEqual(m, 0) 539a46c0ec8Sopenharmony_ci self.assertLessEqual(m, 3) 540a46c0ec8Sopenharmony_ci 541a46c0ec8Sopenharmony_ci s = e["source"] 542a46c0ec8Sopenharmony_ci self.assertIn(s, ["finger", "unknown"]) 543a46c0ec8Sopenharmony_ci 544a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_tool_proximity(self): 545a46c0ec8Sopenharmony_ci keys = ["type", "time", "proximity", "tool-type", "serial", "axes"] 546a46c0ec8Sopenharmony_ci 547a46c0ec8Sopenharmony_ci for e in self.libinput_events("TABLET_TOOL_PROXIMITY"): 548a46c0ec8Sopenharmony_ci for k in keys: 549a46c0ec8Sopenharmony_ci self.assertIn(k, e) 550a46c0ec8Sopenharmony_ci 551a46c0ec8Sopenharmony_ci p = e["proximity"] 552a46c0ec8Sopenharmony_ci self.assertIn(p, ["in", "out"]) 553a46c0ec8Sopenharmony_ci 554a46c0ec8Sopenharmony_ci p = e["tool-type"] 555a46c0ec8Sopenharmony_ci self.assertIn( 556a46c0ec8Sopenharmony_ci p, ["pen", "eraser", "brush", "airbrush", "mouse", "lens", "unknown"] 557a46c0ec8Sopenharmony_ci ) 558a46c0ec8Sopenharmony_ci 559a46c0ec8Sopenharmony_ci s = e["serial"] 560a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(s, int)) 561a46c0ec8Sopenharmony_ci self.assertGreaterEqual(s, 0) 562a46c0ec8Sopenharmony_ci 563a46c0ec8Sopenharmony_ci a = e["axes"] 564a46c0ec8Sopenharmony_ci for ax in e["axes"]: 565a46c0ec8Sopenharmony_ci self.assertIn(a, "pdtrsw") 566a46c0ec8Sopenharmony_ci 567a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_tool(self): 568a46c0ec8Sopenharmony_ci keys = ["type", "time", "tip"] 569a46c0ec8Sopenharmony_ci 570a46c0ec8Sopenharmony_ci for e in self.libinput_events(["TABLET_TOOL_AXIS", "TABLET_TOOL_TIP"]): 571a46c0ec8Sopenharmony_ci for k in keys: 572a46c0ec8Sopenharmony_ci self.assertIn(k, e) 573a46c0ec8Sopenharmony_ci 574a46c0ec8Sopenharmony_ci t = e["tip"] 575a46c0ec8Sopenharmony_ci self.assertIn(t, ["down", "up"]) 576a46c0ec8Sopenharmony_ci 577a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_tool_button(self): 578a46c0ec8Sopenharmony_ci keys = ["type", "time", "button", "state"] 579a46c0ec8Sopenharmony_ci 580a46c0ec8Sopenharmony_ci for e in self.libinput_events("TABLET_TOOL_BUTTON"): 581a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 582a46c0ec8Sopenharmony_ci 583a46c0ec8Sopenharmony_ci b = e["button"] 584a46c0ec8Sopenharmony_ci # STYLUS, STYLUS2, STYLUS3 585a46c0ec8Sopenharmony_ci self.assertIn(b, [0x14B, 0x14C, 0x139]) 586a46c0ec8Sopenharmony_ci 587a46c0ec8Sopenharmony_ci s = e["state"] 588a46c0ec8Sopenharmony_ci self.assertIn(s, ["pressed", "released"]) 589a46c0ec8Sopenharmony_ci 590a46c0ec8Sopenharmony_ci def test_events_libinput_tablet_tool_axes(self): 591a46c0ec8Sopenharmony_ci for e in self.libinput_events( 592a46c0ec8Sopenharmony_ci ["TABLET_TOOL_PROXIMITY", "TABLET_TOOL_AXIS", "TABLET_TOOL_TIP"] 593a46c0ec8Sopenharmony_ci ): 594a46c0ec8Sopenharmony_ci 595a46c0ec8Sopenharmony_ci point = e["point"] 596a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(point, list)) 597a46c0ec8Sopenharmony_ci self.assertEqual(len(point), 2) 598a46c0ec8Sopenharmony_ci for p in point: 599a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 600a46c0ec8Sopenharmony_ci self.assertGreater(p, 0.0) 601a46c0ec8Sopenharmony_ci 602a46c0ec8Sopenharmony_ci try: 603a46c0ec8Sopenharmony_ci tilt = e["tilt"] 604a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(tilt, list)) 605a46c0ec8Sopenharmony_ci self.assertEqual(len(tilt), 2) 606a46c0ec8Sopenharmony_ci for t in tilt: 607a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(t, float)) 608a46c0ec8Sopenharmony_ci except KeyError: 609a46c0ec8Sopenharmony_ci pass 610a46c0ec8Sopenharmony_ci 611a46c0ec8Sopenharmony_ci try: 612a46c0ec8Sopenharmony_ci d = e["distance"] 613a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(d, float)) 614a46c0ec8Sopenharmony_ci self.assertGreaterEqual(d, 0.0) 615a46c0ec8Sopenharmony_ci self.assertNotIn("pressure", e) 616a46c0ec8Sopenharmony_ci except KeyError: 617a46c0ec8Sopenharmony_ci pass 618a46c0ec8Sopenharmony_ci 619a46c0ec8Sopenharmony_ci try: 620a46c0ec8Sopenharmony_ci p = e["pressure"] 621a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(p, float)) 622a46c0ec8Sopenharmony_ci self.assertGreaterEqual(p, 0.0) 623a46c0ec8Sopenharmony_ci self.assertNotIn("distance", e) 624a46c0ec8Sopenharmony_ci except KeyError: 625a46c0ec8Sopenharmony_ci pass 626a46c0ec8Sopenharmony_ci 627a46c0ec8Sopenharmony_ci try: 628a46c0ec8Sopenharmony_ci r = e["rotation"] 629a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(r, float)) 630a46c0ec8Sopenharmony_ci self.assertGreaterEqual(r, 0.0) 631a46c0ec8Sopenharmony_ci except KeyError: 632a46c0ec8Sopenharmony_ci pass 633a46c0ec8Sopenharmony_ci 634a46c0ec8Sopenharmony_ci try: 635a46c0ec8Sopenharmony_ci s = e["slider"] 636a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(s, float)) 637a46c0ec8Sopenharmony_ci self.assertGreaterEqual(s, 0.0) 638a46c0ec8Sopenharmony_ci except KeyError: 639a46c0ec8Sopenharmony_ci pass 640a46c0ec8Sopenharmony_ci 641a46c0ec8Sopenharmony_ci try: 642a46c0ec8Sopenharmony_ci w = e["wheel"] 643a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(w, float)) 644a46c0ec8Sopenharmony_ci self.assertGreaterEqual(w, 0.0) 645a46c0ec8Sopenharmony_ci self.assertIn("wheel-discrete", e) 646a46c0ec8Sopenharmony_ci wd = e["wheel-discrete"] 647a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(wd, 1)) 648a46c0ec8Sopenharmony_ci self.assertGreaterEqual(wd, 0.0) 649a46c0ec8Sopenharmony_ci 650a46c0ec8Sopenharmony_ci def sign(x): 651a46c0ec8Sopenharmony_ci (1, -1)[x < 0] 652a46c0ec8Sopenharmony_ci 653a46c0ec8Sopenharmony_ci self.assertTrue(sign(w), sign(wd)) 654a46c0ec8Sopenharmony_ci except KeyError: 655a46c0ec8Sopenharmony_ci pass 656a46c0ec8Sopenharmony_ci 657a46c0ec8Sopenharmony_ci def test_events_libinput_switch(self): 658a46c0ec8Sopenharmony_ci keys = ["type", "time", "switch", "state"] 659a46c0ec8Sopenharmony_ci 660a46c0ec8Sopenharmony_ci for e in self.libinput_events("SWITCH_TOGGLE"): 661a46c0ec8Sopenharmony_ci self.dict_key_crosscheck(e, keys) 662a46c0ec8Sopenharmony_ci 663a46c0ec8Sopenharmony_ci s = e["switch"] 664a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(s, int)) 665a46c0ec8Sopenharmony_ci self.assertIn(s, [0x00, 0x01]) 666a46c0ec8Sopenharmony_ci 667a46c0ec8Sopenharmony_ci # yaml converts on/off to true/false 668a46c0ec8Sopenharmony_ci state = e["state"] 669a46c0ec8Sopenharmony_ci self.assertTrue(isinstance(state, bool)) 670a46c0ec8Sopenharmony_ci 671a46c0ec8Sopenharmony_ci 672a46c0ec8Sopenharmony_ciif __name__ == "__main__": 673a46c0ec8Sopenharmony_ci parser = argparse.ArgumentParser(description="Verify a YAML recording") 674a46c0ec8Sopenharmony_ci parser.add_argument( 675a46c0ec8Sopenharmony_ci "recording", 676a46c0ec8Sopenharmony_ci metavar="recorded-file.yaml", 677a46c0ec8Sopenharmony_ci type=str, 678a46c0ec8Sopenharmony_ci help="Path to device recording", 679a46c0ec8Sopenharmony_ci ) 680a46c0ec8Sopenharmony_ci parser.add_argument("--verbose", action="store_true") 681a46c0ec8Sopenharmony_ci args, remainder = parser.parse_known_args() 682a46c0ec8Sopenharmony_ci TestYaml.filename = args.recording 683a46c0ec8Sopenharmony_ci verbosity = 1 684a46c0ec8Sopenharmony_ci if args.verbose: 685a46c0ec8Sopenharmony_ci verbosity = 3 686a46c0ec8Sopenharmony_ci 687a46c0ec8Sopenharmony_ci argv = [sys.argv[0], *remainder] 688a46c0ec8Sopenharmony_ci unittest.main(argv=argv, verbosity=verbosity) 689