diff --git a/README.md b/README.md index 8b80dbb..ac8f760 100644 --- a/README.md +++ b/README.md @@ -244,4 +244,6 @@ pytest -m smokewifi meshtastic/test/test_smoke_wifi.py::test_smokewifi_info ``` pytest --cov=meshtastic +# or if want html coverage report +pytest --cov-report html --cov=meshtastic ``` diff --git a/meshtastic/__main__.py b/meshtastic/__main__.py index 3460574..9b037d4 100644 --- a/meshtastic/__main__.py +++ b/meshtastic/__main__.py @@ -23,17 +23,43 @@ from .util import support_info, our_exit """We only import the tunnel code if we are on a platform that can run it""" have_tunnel = platform.system() == 'Linux' -"""The command line arguments""" -args = None - -"""The parser for arguments""" -parser = argparse.ArgumentParser() - channelIndex = 0 +class Settings: + """Settings class is a Singleton.""" + __instance = None + @staticmethod + def getInstance(): + """Get an instance of the Settings class.""" + if Settings.__instance is None: + Settings() + return Settings.__instance + def __init__(self): + """Constructor for the Settings CLass""" + if Settings.__instance is not None: + raise Exception("This class is a singleton") + else: + Settings.__instance = self + self.args = None + self.parser = None + def set_args(self, args): + """Set the args""" + self.args = args + def set_parser(self, parser): + """Set the parser""" + self.parser = parser + def get_args(self): + """Get args""" + return self.args + def get_parser(self): + """Get parser""" + return self.parser + def onReceive(packet, interface): """Callback invoked when a packet arrives""" + settings = Settings.getInstance() + args = settings.get_args() try: d = packet.get('decoded') @@ -197,7 +223,8 @@ def onConnected(interface): """Callback invoked when we connect to a radio""" closeNow = False # Should we drop the connection after we finish? try: - global args + settings = Settings.getInstance() + args = settings.get_args() print("Connected to radio") @@ -564,7 +591,9 @@ def subscribe(): def common(): """Shared code for all of our command line wrappers""" - global args + settings = Settings.getInstance() + args = settings.get_args() + parser = settings.get_parser() logging.basicConfig(level=logging.DEBUG if args.debug else logging.INFO) if len(sys.argv) == 1: @@ -641,7 +670,9 @@ def common(): def initParser(): """ Initialize the command line argument parsing.""" - global parser, args + settings = Settings.getInstance() + parser = settings.get_parser() + args = settings.get_args() parser.add_argument( "--configure", @@ -806,19 +837,28 @@ def initParser(): "--support", action='store_true', help="Show support info (useful when troubleshooting an issue)") args = parser.parse_args() + settings.set_args(args) + settings.set_parser(parser) def main(): """Perform command line meshtastic operations""" + settings = Settings.getInstance() + parser = argparse.ArgumentParser() + settings.set_parser(parser) initParser() common() def tunnelMain(): """Run a meshtastic IP tunnel""" - global args + settings = Settings.getInstance() + parser = argparse.ArgumentParser() + settings.set_parser(parser) initParser() + args = settings.get_args() args.tunnel = True + settings.set_args(args) common() diff --git a/meshtastic/test/test_main.py b/meshtastic/test/test_main.py new file mode 100644 index 0000000..186e8de --- /dev/null +++ b/meshtastic/test/test_main.py @@ -0,0 +1,55 @@ +"""Meshtastic unit tests for __main__.py""" + +import sys +import argparse +import re + +import pytest + +from meshtastic.__main__ import initParser, Settings + + +"""The command line arguments""" +#args = None + +"""The parser for arguments""" +#parser = None + +#@pytest.fixture +#def patched_env(monkeypatch): +# monkeypatch.args = None +# #monkeypatch.sys.argv = [''] +# monkeypatch.parser = None + +@pytest.mark.unit +def test_main_no_args(capsys): + """Test no arguments""" + sys.argv = [''] + args = sys.argv + settings = Settings.getInstance() + parser = argparse.ArgumentParser() + settings.set_parser(parser) + settings.set_args(args) + initParser() + out, err = capsys.readouterr() + assert out == '' + assert err == '' + + +@pytest.mark.unit +def test_main_version(capsys): + """Test --version""" + sys.argv = ['', '--version'] + args = sys.argv + parser = None + parser = argparse.ArgumentParser() + settings = Settings.getInstance() + settings.set_parser(parser) + settings.set_args(args) + with pytest.raises(SystemExit) as pytest_wrapped_e: + initParser() + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 0 + out, err = capsys.readouterr() + assert re.match(r'[0-9]+\.[0-9]+\.[0-9]', out) + assert err == ''