Files
contact/tests/test_cli.py
T
pdxlocations dfa0a892c0 Refactor command-line interface and settings management
- Consolidated command-line argument parsing and handling into a unified structure.
- Introduced a new runtime module to manage the main application logic.
- Updated settings management to streamline the user experience and improve error handling.
- Enhanced versioning and help display functionality across the application.
- Refactored UI components to ensure compatibility with the new command structure.
- Added comprehensive tests for CLI functionality and settings management.
2026-09-15 22:23:16 -07:00

64 lines
3.0 KiB
Python

import os
from pathlib import Path
import subprocess
import sys
import tempfile
from types import SimpleNamespace
import unittest
from unittest import mock
import contact.__main__ as cli
import contact.settings as settings_cli
from contact.version import __version__
class CliTests(unittest.TestCase):
def test_help_version_and_errors_work_without_runtime_configuration(self) -> None:
cases = [
(["--help"], 0, "usage:"),
(["-h"], 0, "usage:"),
(["--version"], 0, __version__),
(["-V"], 0, __version__),
(["--unknown"], 2, "unrecognized arguments"),
(["--host", "localhost", "--ble"], 2, "not allowed with argument"),
(["--", "--version"], 2, "unrecognized arguments"),
]
with tempfile.TemporaryDirectory() as directory:
config_root = Path(directory) / "missing"
env = dict(os.environ, CONTACT_CONFIG_ROOT=str(config_root))
for command in (["-m", "contact"], ["-m", "contact.settings"],
["-c", "from contact.__main__ import start; start()"]):
for flags, code, expected in cases:
with self.subTest(command=command, flags=flags):
result = subprocess.run(
[sys.executable, *command, *flags], env=env,
capture_output=True, text=True, timeout=10,
)
self.assertEqual(result.returncode, code, result.stderr)
self.assertIn(expected, result.stderr if code else result.stdout)
self.assertEqual(result.stdout if code else result.stderr, "")
self.assertFalse(config_root.exists())
def test_control_aliases_preserve_connection_options(self) -> None:
for alias in ("--settings", "--set", "--control", "-c"):
for connection, value, attribute in (
("--host", "mesh.local", "host"),
("--port", "/dev/ttyUSB0", "port"),
("--ble", "my-radio", "ble"),
):
with self.subTest(alias=alias, connection=connection):
runtime = SimpleNamespace(start=mock.Mock())
with mock.patch.dict(sys.modules, {"contact.settings_runtime": runtime}):
cli.start([alias, connection, value])
runtime.start.assert_called_once()
self.assertEqual(getattr(runtime.start.call_args.args[0], attribute), value)
def test_main_and_standalone_settings_pass_parsed_options(self) -> None:
for entrypoint, module in ((cli, "contact.runtime"),
(settings_cli, "contact.settings_runtime")):
runtime = SimpleNamespace(start=mock.Mock())
with mock.patch.dict(sys.modules, {module: runtime}):
entrypoint.start(["--host=mesh.local"])
runtime.start.assert_called_once()
self.assertEqual(runtime.start.call_args.args[0].host, "mesh.local")