Add MX-T40 BLE desktop controller and protocol documentation
Checks / tests (ubuntu-latest, 3.11) (push) Canceled after 0s
Checks / tests (ubuntu-latest, 3.14) (push) Canceled after 0s
Checks / tests (windows-latest, 3.11) (push) Canceled after 0s
Checks / tests (windows-latest, 3.14) (push) Canceled after 0s
Checks / package (push) Canceled after 0s
Checks / tests (ubuntu-latest, 3.11) (push) Canceled after 0s
Checks / tests (ubuntu-latest, 3.14) (push) Canceled after 0s
Checks / tests (windows-latest, 3.11) (push) Canceled after 0s
Checks / tests (windows-latest, 3.14) (push) Canceled after 0s
Checks / package (push) Canceled after 0s
This commit is contained in:
38 files changed
+2344
No files matched your search
@@ -0,0 +1,88 @@
|
||||
"""Model the named overloads exported by Python/WinRT, not C# overloads."""
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import io
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from controller.probe import SPP_UUID, check_channel, probe
|
||||
|
||||
|
||||
class ProbeTests(unittest.TestCase):
|
||||
def test_projected_overloads_and_resource_cleanup(self):
|
||||
closed = []
|
||||
selector = "paired Bluetooth selector"
|
||||
service = types.SimpleNamespace(
|
||||
service_id=types.SimpleNamespace(uuid=SPP_UUID),
|
||||
connection_host_name=types.SimpleNamespace(raw_name="speaker-host"),
|
||||
connection_service_name="1",
|
||||
close=lambda: closed.append("service"),
|
||||
)
|
||||
|
||||
async def get_services(cache_mode):
|
||||
self.assertEqual(cache_mode, 1)
|
||||
return types.SimpleNamespace(error=0, services=[service])
|
||||
|
||||
async def from_id(device_id):
|
||||
self.assertEqual(device_id, "device-id")
|
||||
return types.SimpleNamespace(
|
||||
bluetooth_address=0x123456789ABC,
|
||||
get_rfcomm_services_with_cache_mode_async=get_services,
|
||||
close=lambda: closed.append("device"),
|
||||
)
|
||||
|
||||
async def find_filtered(value):
|
||||
self.assertEqual(value, selector)
|
||||
return [types.SimpleNamespace(name="MX-T40", id="device-id")]
|
||||
|
||||
def wrong_overload(value):
|
||||
# The installed projection treats this argument as DeviceClass.
|
||||
raise TypeError("'str' object cannot be interpreted as an integer")
|
||||
|
||||
bluetooth = types.SimpleNamespace(
|
||||
BluetoothCacheMode=types.SimpleNamespace(UNCACHED=1),
|
||||
BluetoothDevice=types.SimpleNamespace(
|
||||
get_device_selector_from_pairing_state=lambda paired: selector,
|
||||
from_id_async=from_id,
|
||||
),
|
||||
)
|
||||
enumeration = types.SimpleNamespace(
|
||||
DeviceInformation=types.SimpleNamespace(
|
||||
find_all_async=wrong_overload,
|
||||
find_all_async_aqs_filter=find_filtered,
|
||||
)
|
||||
)
|
||||
with (
|
||||
patch.dict(
|
||||
sys.modules,
|
||||
{
|
||||
"winrt.windows.devices.bluetooth": bluetooth,
|
||||
"winrt.windows.devices.enumeration": enumeration,
|
||||
},
|
||||
),
|
||||
contextlib.redirect_stdout(io.StringIO()) as output,
|
||||
):
|
||||
result = asyncio.run(probe("MX-T40"))
|
||||
self.assertEqual(result, 0)
|
||||
self.assertIn("SPP service found: True", output.getvalue())
|
||||
self.assertEqual(closed, ["service", "device"])
|
||||
|
||||
def test_direct_channel_connects_without_sending(self):
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
stream = MagicMock()
|
||||
with (
|
||||
patch("controller.probe.socket.socket") as create,
|
||||
patch("controller.probe.socket.AF_BLUETOOTH", 32, create=True),
|
||||
patch("controller.probe.socket.BTPROTO_RFCOMM", 3, create=True),
|
||||
):
|
||||
create.return_value.__enter__.return_value = stream
|
||||
check_channel("12:34:56:78:9A:BC", 1)
|
||||
stream.connect.assert_called_once_with(("12:34:56:78:9A:BC", 1))
|
||||
stream.settimeout.assert_called_once_with(10)
|
||||
stream.send.assert_not_called()
|
||||
stream.sendall.assert_not_called()
|
||||
create.return_value.__exit__.assert_called_once()
|
||||
Reference in new issue
Block a user