Coverage for tests/tests_cli/test_client.py: 79%
67 statements
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:44 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2026-01-05 21:44 +0100
1#!/usr/bin/env python3
2"""Unittests for the ramses_cli client.py class."""
4import io
5from collections.abc import Generator
6from unittest.mock import AsyncMock, MagicMock
8import pytest
9from click.testing import CliRunner
11from ramses_cli.client import cli
12from ramses_rf.database import MessageIndex
13from ramses_rf.gateway import Gateway
15STDIN = io.StringIO("053 I --- 01:123456 --:------ 01:123456 3150 002 FC00\r\n")
16CMD = "RQ 01:123456 1F09 00"
19@pytest.fixture
20def mock_gateway() -> Generator[MagicMock, None, None]:
21 """Create a mock Gateway instance for testing."""
22 gateway = MagicMock(spec=Gateway)
23 gateway.send_cmd = AsyncMock()
24 gateway.dispatcher = MagicMock()
25 gateway.dispatcher.send = MagicMock()
27 # Add required attributes
28 gateway.config = MagicMock()
29 gateway.config.disable_discovery = False
30 gateway.config.enable_eavesdrop = False
31 gateway._loop = MagicMock()
32 gateway._loop.call_soon = MagicMock()
33 gateway._loop.call_later = MagicMock()
34 gateway._loop.time = MagicMock(return_value=0.0)
35 gateway._include = {}
36 # Add msg_db attribute accessed by the message store, activates the SQLite MessageIndex
37 gateway.msg_db = MessageIndex(maintain=False)
39 yield gateway
42def test_parse_no_input() -> None:
43 runner = CliRunner()
44 result = runner.invoke(cli, ["parse"])
45 assert result.exit_code == 2 # missing input file
46 assert result.output.startswith("Usage: cli parse [OPTIONS] INPUT_FILE")
49def test_parse(monkeypatch: pytest.MonkeyPatch) -> None:
50 monkeypatch.setattr("sys.stdin", STDIN)
51 runner = CliRunner()
52 result = runner.invoke(cli, ["parse", "-"])
53 assert result.exit_code == 0 # OK input file supplied
54 assert result.output == ""
57def test_monitor_no_port() -> None:
58 runner = CliRunner()
59 result = runner.invoke(cli, ["monitor"])
60 assert result.exit_code == 2 # missing port name
61 assert result.output.startswith("Usage: cli monitor [OPTIONS] SERIAL_PORT")
64def test_monitor(monkeypatch: pytest.MonkeyPatch) -> None:
65 runner = CliRunner()
66 result = runner.invoke(cli, ["monitor", "nullmodem"])
67 assert result.exit_code == 0 # OK port name supplied
68 assert result.output == " - discovery is enabled\n"
71def test_execute_no_arg() -> None:
72 runner = CliRunner()
73 result = runner.invoke(cli, ["execute"])
74 assert result.exit_code == 2 # missing command, port
75 assert result.output.startswith("Usage: cli execute [OPTIONS] SERIAL_PORT")
78def test_execute(monkeypatch: pytest.MonkeyPatch) -> None:
79 runner = CliRunner()
80 result = runner.invoke(cli, ["execute", CMD])
81 assert result.exit_code == 0 # OK command supplied
82 assert result.output == " - discovery is force-disabled\n"
85def test_listen_no_arg() -> None:
86 runner = CliRunner()
87 result = runner.invoke(cli, ["listen"])
88 assert result.exit_code == 2 # missing port
89 assert result.output.startswith("Usage: cli listen [OPTIONS] SERIAL_PORT")
92def test_listen(monkeypatch: pytest.MonkeyPatch) -> None:
93 runner = CliRunner()
94 result = runner.invoke(cli, ["listen", "nullmodem"])
95 assert result.exit_code == 0 # OK port supplied
96 assert result.output == " - sending is force-disabled\n"
99# def test_convert() -> None:
100# assert False
101#
102#
103# def test_cli():
104# assert False
105#
106#
107# def test_file_command():
108# assert False
109#
110#
111# def test_file_cli():
112# assert False
113#
114#
115# def test_port_command():
116# assert False
117#
118#
119# def test_port_cli():
120# assert False
121#
122#
123# def test_parse_cli():
124# assert False
125#
126#
127# def test_print_results():
128# assert False
129#
130#
131# def test__save_state():
132# assert False
133#
134#
135# def test__print_engine_state():
136# assert False
137#
138#
139# def test_print_summary():
140# assert False