"""CLI behaviour: exit codes, output modes and argument handling.""" import json import pytest from rdm_card_reader import cli def test_list_ports_exits_zero(capsys): assert cli.main(["--list-ports"]) == cli.EXIT_OK out = capsys.readouterr().out assert "/dev/ttyS0" in out def test_demo_exits_zero(capsys): assert cli.main(["--demo", "--demo-count", "1"]) == cli.EXIT_OK assert "CARD INSERTED" in capsys.readouterr().out def test_demo_json_emits_one_object_per_event(capsys): cli.main(["--demo", "--demo-count", "1", "--json"]) lines = [line for line in capsys.readouterr().out.splitlines() if line.strip()] events = [json.loads(line) for line in lines if line.startswith("{")] assert events assert {"event", "timestamp", "id", "hex"} <= set(events[0]) def test_demo_count_is_respected(capsys): cli.main(["--demo", "--demo-count", "4"]) assert capsys.readouterr().out.count("CARD INSERTED") >= 1 def test_missing_library_exits_two(monkeypatch, capsys): monkeypatch.setattr(cli, "available", lambda: False) assert cli.main([]) == cli.EXIT_NO_LIBRARY assert "rdm6300" in capsys.readouterr().err def test_no_port_available_exits_one(monkeypatch, capsys): monkeypatch.setattr(cli, "available", lambda: True) monkeypatch.setattr(cli, "open_reader", lambda *a, **kw: None) assert cli.main(["--port", "/dev/nope"]) == cli.EXIT_NO_PORT assert "Could not open any serial port" in capsys.readouterr().err def test_explicit_port_is_the_only_one_tried(monkeypatch): monkeypatch.setattr(cli, "available", lambda: True) tried = [] def fake_open(callback, ports=None, **kwargs): tried.extend(ports or []) return None monkeypatch.setattr(cli, "open_reader", fake_open) cli.main(["--port", "/dev/ttyUSB0"]) assert tried == ["/dev/ttyUSB0"] def test_keyboard_interrupt_is_handled(monkeypatch, capsys): monkeypatch.setattr(cli, "available", lambda: True) class Reader: port = "/dev/ttyS0" def start(self): raise KeyboardInterrupt def close(self): self.closed = True reader = Reader() monkeypatch.setattr(cli, "open_reader", lambda *a, **kw: reader) assert cli.main([]) == cli.EXIT_OK assert reader.closed is True assert "Stopped by user" in capsys.readouterr().out def test_version_flag_exits_zero(capsys): with pytest.raises(SystemExit) as exc: cli.main(["--version"]) assert exc.value.code == 0 assert "rdm-card-reader" in capsys.readouterr().out def test_json_mode_prints_json_from_the_callback(capsys): printer = cli._make_printer(as_json=True) from rdm_card_reader.card import CardEvent printer(CardEvent("card_inserted", "-", 1, 2, 15, True, "p")) payload = json.loads(capsys.readouterr().out.strip()) assert payload["id"] == 1