From a15bb462d4ee6d6b42ae5de36811781e54bec33b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9phine=20Wolf=20Oberholtzer?= <166141926+josephine-wolf-oberholtzer@users.noreply.github.com> Date: Fri, 20 Dec 2024 15:51:00 -0500 Subject: [PATCH] SUPRIYA-409: Fix hardware device options (#411) --- supriya/scsynth.py | 22 +++++++---- tests/test_scsynth.py | 88 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 7 deletions(-) diff --git a/supriya/scsynth.py b/supriya/scsynth.py index 1c6a7ea58..e51dcd7cf 100644 --- a/supriya/scsynth.py +++ b/supriya/scsynth.py @@ -10,7 +10,7 @@ import threading from dataclasses import dataclass from pathlib import Path -from typing import IO, Callable, Dict, Iterator, List, Optional, Set, Tuple, cast +from typing import IO, Callable, Dict, Iterator, List, Optional, Set, Tuple, Union, cast import psutil import uqbar.io @@ -120,16 +120,20 @@ def get_sync_ids(self, client_id: int) -> Tuple[int, int]: def serialize(self) -> List[str]: result = [str(find(self.executable))] - pairs: Dict[str, Optional[str]] = {} + pairs: Dict[str, Optional[Union[List[str], str]]] = {} if self.realtime: if self.protocol == "tcp": pairs["-t"] = str(self.port) else: pairs["-u"] = str(self.port) - if self.input_device: - pairs["-H"] = str(self.input_device) - if self.output_device != self.input_device: - result.append(str(self.output_device)) + if self.input_device == self.output_device: + if self.input_device: + pairs["-H"] = str(self.input_device) + else: + pairs["-H"] = [ + str(self.input_device or ""), + str(self.output_device or ""), + ] if self.maximum_logins != 64: pairs["-l"] = str(self.maximum_logins) if self.password: @@ -179,7 +183,11 @@ def serialize(self) -> List[str]: if self.threads and find(self.executable).stem == "supernova": pairs["-t"] = str(self.threads) for key, value in sorted(pairs.items()): - result.extend([key, value] if value is not None else [key]) + result.append(key) + if isinstance(value, str): + result.append(value) + elif isinstance(value, list): + result.extend(value) return result ### PUBLIC PROPERTIES ### diff --git a/tests/test_scsynth.py b/tests/test_scsynth.py index b774fde85..f668e5522 100644 --- a/tests/test_scsynth.py +++ b/tests/test_scsynth.py @@ -2,6 +2,7 @@ import pathlib import stat from tempfile import NamedTemporaryFile, TemporaryDirectory +from typing import Dict, List import pytest @@ -40,3 +41,90 @@ def test_find_on_path(mock_env_scsynth_path, monkeypatch): got = scsynth.find() expected = scsynth_path.resolve().absolute() assert got == expected + + +@pytest.mark.parametrize( + "kwargs, expected", + [ + ( + {}, + [ + "/path/to/scsynth", + "-R", + "0", + "-l", + "1", + "-u", + "57110", + ], + ), + # only input device defined + ( + {"input_device": "Device X"}, + [ + "/path/to/scsynth", + "-H", + "Device X", + "", + "-R", + "0", + "-l", + "1", + "-u", + "57110", + ], + ), + # only output device defined + ( + {"output_device": "Device Y"}, + [ + "/path/to/scsynth", + "-H", + "", + "Device Y", + "-R", + "0", + "-l", + "1", + "-u", + "57110", + ], + ), + # input and output devices defined, but different + ( + {"input_device": "Device P", "output_device": "Device Q"}, + [ + "/path/to/scsynth", + "-H", + "Device P", + "Device Q", + "-R", + "0", + "-l", + "1", + "-u", + "57110", + ], + ), + # input and output devices defined, and identical + ( + {"input_device": "Device Z", "output_device": "Device Z"}, + [ + "/path/to/scsynth", + "-H", + "Device Z", + "-R", + "0", + "-l", + "1", + "-u", + "57110", + ], + ), + ], +) +def test_Options(kwargs: Dict, expected: List[str]) -> None: + options = scsynth.Options(**kwargs) + actual = list(options) + actual[0] = "/path/to/scsynth" # replace to make it portable + assert actual == expected