From fca86822df1852cac0cdb0487091aef92182aa20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Schoentgen?= Date: Thu, 20 Apr 2023 07:37:40 +0200 Subject: [PATCH] CLI: fix entry point not taking into account arguments --- CHANGELOG.md | 3 +- src/mss/__main__.py | 9 +++-- src/tests/test_implementation.py | 60 +++++++++++++++++++------------- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5cf753b..f115fa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,7 @@ See Git checking messages for full history. ## 9.0.1 (2023/xx/xx) -- -- :heart: contributors: @ +- CLI: fixed entry point not taking into account arguments ## 9.0.0 (2023/04/18) - Linux: add failure handling to `XOpenDisplay()` call (fixes #246) diff --git a/src/mss/__main__.py b/src/mss/__main__.py index 0aa4398..4dff5a1 100644 --- a/src/mss/__main__.py +++ b/src/mss/__main__.py @@ -3,6 +3,7 @@ Source: https://github.com/BoboTiG/python-mss """ import os.path +import sys from argparse import ArgumentParser from . import __version__ @@ -14,7 +15,7 @@ def main(*args: str) -> int: """Main logic.""" - cli_args = ArgumentParser() + cli_args = ArgumentParser(prog="mss") cli_args.add_argument( "-c", "--coordinates", @@ -42,7 +43,7 @@ def main(*args: str) -> int: ) cli_args.add_argument("-v", "--version", action="version", version=__version__) - options = cli_args.parse_args(args) + options = cli_args.parse_args(args or None) kwargs = {"mon": options.monitor, "output": options.output} if options.coordinates: try: @@ -80,6 +81,4 @@ def main(*args: str) -> int: if __name__ == "__main__": # pragma: nocover - import sys - - sys.exit(main(*sys.argv[1:])) + sys.exit(main()) diff --git a/src/tests/test_implementation.py b/src/tests/test_implementation.py index 2de3b82..caeca22 100644 --- a/src/tests/test_implementation.py +++ b/src/tests/test_implementation.py @@ -5,12 +5,15 @@ import os import os.path import platform -from unittest.mock import patch +import sys +from datetime import datetime +from unittest.mock import Mock, patch import pytest import mss.tools from mss import mss +from mss.__main__ import main as entry_point from mss.base import MSSBase from mss.exception import ScreenShotError from mss.screenshot import ScreenShot @@ -78,12 +81,9 @@ def test_factory(monkeypatch): assert error == "System 'chuck norris' not (yet?) implemented." +@patch.object(sys, "argv", new=[]) # Prevent side effects while testing @pytest.mark.parametrize("with_cursor", [False, True]) def test_entry_point(with_cursor: bool, capsys): - from datetime import datetime - - from mss.__main__ import main as entry_point - def main(*args: str, ret: int = 0) -> None: if with_cursor: args = args + ("--with-cursor",) @@ -91,8 +91,8 @@ def main(*args: str, ret: int = 0) -> None: # No arguments main() - out, _ = capsys.readouterr() - for mon, line in enumerate(out.splitlines(), 1): + captured = capsys.readouterr() + for mon, line in enumerate(captured.out.splitlines(), 1): filename = f"monitor-{mon}.png" assert line.endswith(filename) assert os.path.isfile(filename) @@ -100,24 +100,24 @@ def main(*args: str, ret: int = 0) -> None: for opt in ("-m", "--monitor"): main(opt, "1") - out, _ = capsys.readouterr() - assert out.endswith("monitor-1.png\n") + captured = capsys.readouterr() + assert captured.out.endswith("monitor-1.png\n") assert os.path.isfile("monitor-1.png") os.remove("monitor-1.png") for opt in zip(["-m 1", "--monitor=1"], ["-q", "--quiet"]): main(*opt) - out, _ = capsys.readouterr() - assert not out + captured = capsys.readouterr() + assert not captured.out assert os.path.isfile("monitor-1.png") os.remove("monitor-1.png") fmt = "sct-{mon}-{width}x{height}.png" for opt in ("-o", "--out"): main(opt, fmt) - out, _ = capsys.readouterr() + captured = capsys.readouterr() with mss(display=os.getenv("DISPLAY")) as sct: - for mon, (monitor, line) in enumerate(zip(sct.monitors[1:], out.splitlines()), 1): + for mon, (monitor, line) in enumerate(zip(sct.monitors[1:], captured.out.splitlines()), 1): filename = fmt.format(mon=mon, **monitor) assert line.endswith(filename) assert os.path.isfile(filename) @@ -127,8 +127,8 @@ def main(*args: str, ret: int = 0) -> None: for opt in ("-o", "--out"): main("-m 1", opt, fmt) filename = fmt.format(mon=1, date=datetime.now()) - out, _ = capsys.readouterr() - assert out.endswith(filename + "\n") + captured = capsys.readouterr() + assert captured.out.endswith(filename + "\n") assert os.path.isfile(filename) os.remove(filename) @@ -136,23 +136,22 @@ def main(*args: str, ret: int = 0) -> None: filename = "sct-2x12_40x67.png" for opt in ("-c", "--coordinates"): main(opt, coordinates) - out, _ = capsys.readouterr() - assert out.endswith(filename + "\n") + captured = capsys.readouterr() + assert captured.out.endswith(filename + "\n") assert os.path.isfile(filename) os.remove(filename) coordinates = "2,12,40" for opt in ("-c", "--coordinates"): main(opt, coordinates, ret=2) - out, _ = capsys.readouterr() - assert out == "Coordinates syntax: top, left, width, height\n" + captured = capsys.readouterr() + assert captured.out == "Coordinates syntax: top, left, width, height\n" +@patch.object(sys, "argv", new=[]) # Prevent side effects while testing @patch("mss.base.MSSBase.monitors", new=[]) @pytest.mark.parametrize("quiet", [False, True]) def test_entry_point_error(quiet: bool, capsys): - from mss.__main__ import main as entry_point - def main(*args: str) -> int: if quiet: args = args + ("--quiet",) @@ -160,14 +159,27 @@ def main(*args: str) -> int: if quiet: assert main() == 1 - out, err = capsys.readouterr() - assert not out - assert not err + captured = capsys.readouterr() + assert not captured.out + assert not captured.err else: with pytest.raises(ScreenShotError): main() +def test_entry_point_with_no_argument(capsys): + # Make sure to fail if arguments are not handled + with patch("mss.factory.mss", new=Mock(side_effect=RuntimeError("Boom!"))): + with patch.object(sys, "argv", ["mss", "--help"]): + with pytest.raises(SystemExit) as exc: + entry_point() + assert exc.value.code == 0 + + captured = capsys.readouterr() + assert not captured.err + assert "usage: mss" in captured.out + + def test_grab_with_tuple(pixel_ratio: int): left = 100 top = 100