diff --git a/swh/core/db/tests/test_cli.py b/swh/core/db/tests/test_cli.py --- a/swh/core/db/tests/test_cli.py +++ b/swh/core/db/tests/test_cli.py @@ -13,6 +13,7 @@ from swh.core.cli.db import db as swhdb from swh.core.db import BaseDb from swh.core.db.pytest_plugin import postgresql_fact +from swh.core.tests.test_cli import assert_section_contains @pytest.fixture @@ -20,57 +21,41 @@ return CliRunner() -help_msg = """Usage: swh [OPTIONS] COMMAND [ARGS]... - - Command line interface for Software Heritage. - -Options: - -l, --log-level [NOTSET|DEBUG|INFO|WARNING|ERROR|CRITICAL] - Log level (defaults to INFO). - --log-config FILENAME Python yaml logging configuration file. - --sentry-dsn TEXT DSN of the Sentry instance to report to - -h, --help Show this message and exit. - -Notes: - If both options are present, --log-level will override the root logger - configuration set in --log-config. - - The --log-config YAML must conform to the logging.config.dictConfig schema - documented at https://docs.python.org/3/library/logging.config.html. - -Commands: - db Software Heritage database generic tools. -""" - - def test_cli_swh_help(swhmain, cli_runner): swhmain.add_command(swhdb) result = cli_runner.invoke(swhmain, ["-h"]) assert result.exit_code == 0 - assert result.output == help_msg - - -help_db_msg = """Usage: swh db [OPTIONS] COMMAND [ARGS]... - - Software Heritage database generic tools. + assert_section_contains( + result.output, "Commands", "db Software Heritage database generic tools." + ) -Options: - -C, --config-file FILE Configuration file. - -h, --help Show this message and exit. -Commands: - create Create a database for the Software Heritage . - init Initialize a database for the Software Heritage . - init-admin Execute superuser-level initialization steps (e.g pg - extensions,... -""" +help_db_snippets = ( + ( + "Usage", + ( + "Usage: swh db [OPTIONS] COMMAND [ARGS]...", + "Software Heritage database generic tools.", + ), + ), + ( + "Commands", + ( + "create Create a database for the Software Heritage .", + "init Initialize a database for the Software Heritage .", + "init-admin Execute superuser-level initialization steps", + ), + ), +) def test_cli_swh_db_help(swhmain, cli_runner): swhmain.add_command(swhdb) result = cli_runner.invoke(swhmain, ["db", "-h"]) assert result.exit_code == 0 - assert result.output == help_db_msg + for section, snippets in help_db_snippets: + for snippet in snippets: + assert_section_contains(result.output, section, snippet) @pytest.fixture() diff --git a/swh/core/tests/test_cli.py b/swh/core/tests/test_cli.py --- a/swh/core/tests/test_cli.py +++ b/swh/core/tests/test_cli.py @@ -5,6 +5,7 @@ import logging import textwrap +from typing import List from unittest.mock import patch import click @@ -12,35 +13,68 @@ import pkg_resources import pytest -help_msg = """Usage: swh [OPTIONS] COMMAND [ARGS]... - - Command line interface for Software Heritage. - -Options: - -l, --log-level [NOTSET|DEBUG|INFO|WARNING|ERROR|CRITICAL] - Log level (defaults to INFO). - --log-config FILENAME Python yaml logging configuration file. - --sentry-dsn TEXT DSN of the Sentry instance to report to - -h, --help Show this message and exit. - -Notes: - If both options are present, --log-level will override the root logger - configuration set in --log-config. - - The --log-config YAML must conform to the logging.config.dictConfig schema - documented at https://docs.python.org/3/library/logging.config.html. -""" +help_msg_snippets = ( + ( + "Usage", + ( + "swh [OPTIONS] COMMAND [ARGS]...", + "Command line interface for Software Heritage.", + ), + ), + ("Options", ("-l, --log-level", "--log-config", "--sentry-dsn", "-h, --help",)), +) + + +def get_section(cli_output: str, section: str) -> List[str]: + """Get the given `section` of the `cli_output`""" + result = [] + in_section = False + for line in cli_output.splitlines(): + if not line: + continue + + if in_section: + if not line.startswith(" "): + break + else: + if line.startswith(section): + in_section = True + + if in_section: + result.append(line) + + return result + + +def assert_section_contains(cli_output: str, section: str, snippet: str) -> bool: + """Check that a given `section` of the `cli_output` contains the given `snippet`""" + section_lines = get_section(cli_output, section) + assert section_lines, "Section %s not found in output %r" % (section, cli_output) + + for line in section_lines: + if snippet in line: + return True + else: + assert False, "%r not found in section %r of output %r" % ( + snippet, + section, + cli_output, + ) def test_swh_help(swhmain): runner = CliRunner() result = runner.invoke(swhmain, ["-h"]) assert result.exit_code == 0 - assert result.output.startswith(help_msg) + for section, snippets in help_msg_snippets: + for snippet in snippets: + assert_section_contains(result.output, section, snippet) result = runner.invoke(swhmain, ["--help"]) assert result.exit_code == 0 - assert result.output.startswith(help_msg) + for section, snippets in help_msg_snippets: + for snippet in snippets: + assert_section_contains(result.output, section, snippet) def test_command(swhmain): @@ -67,7 +101,6 @@ runner = CliRunner() result = runner.invoke(swhmain, ["test"]) assert result.exit_code == 0 - print(result.output) assert result.output.strip() == """Hello SWH!"""