Source code for click_extra.tests.test_version

# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""Test the ``--version`` option.

.. todo::
    Test standalone scripts setting package name to filename and version to
    `None`.

.. todo::
    Test standalone script fetching version from ``__version__`` variable.
"""

from __future__ import annotations

import re

import click
import pytest
from boltons.strutils import strip_ansi
from pytest_cases import parametrize

from click_extra import ExtraVersionOption, Style, __version__, echo, pass_context
from click_extra.decorators import (
    color_option,
    extra_group,
    extra_version_option,
    verbosity_option,
)

from .conftest import (
    command_decorators,
    default_debug_colored_log_end,
    default_debug_colored_logging,
    default_debug_colored_version_details,
    skip_windows_colors,
)


[docs]@skip_windows_colors @parametrize("cmd_decorator", command_decorators()) @parametrize("option_decorator", (extra_version_option, extra_version_option())) def test_standalone_version_option(invoke, cmd_decorator, option_decorator): @cmd_decorator @option_decorator def standalone_option(): echo("It works!") result = invoke(standalone_option, "--version", color=True) assert result.exit_code == 0 assert not result.stderr assert result.output == ( "\x1b[97mstandalone-option\x1b[0m, " f"version \x1b[32m{__version__}" "\x1b[0m\n" )
[docs]@skip_windows_colors @parametrize("cmd_decorator", command_decorators()) @parametrize("option_decorator", (extra_version_option, extra_version_option())) def test_debug_output(invoke, cmd_decorator, option_decorator): @cmd_decorator @verbosity_option @option_decorator def debug_output(): echo("It works!") result = invoke(debug_output, "--verbosity", "DEBUG", "--version", color=True) assert result.exit_code == 0 assert re.fullmatch( ( default_debug_colored_logging + default_debug_colored_version_details + r"\x1b\[97mdebug-output\x1b\[0m, " rf"version \x1b\[32m{re.escape(__version__)}\x1b\[0m\n" + default_debug_colored_log_end ), result.output, )
[docs]@skip_windows_colors def test_set_version(invoke): @click.group @extra_version_option(version="1.2.3.4") def color_cli2(): echo("It works!") # Test default coloring. result = invoke(color_cli2, "--version", color=True) assert result.exit_code == 0 assert not result.stderr assert result.stdout == ( "\x1b[97mcolor-cli2\x1b[0m, version \x1b[32m1.2.3.4\x1b[0m\n" )
[docs]@skip_windows_colors @parametrize("cmd_decorator", command_decorators(no_groups=True)) @parametrize( "message, regex_stdout", ( ( "{prog_name}, version {version}", r"\x1b\[97mcolor-cli3\x1b\[0m, " rf"version \x1b\[32m{re.escape(__version__)}" r"\x1b\[0m\n", ), ( "{prog_name}, version {version}\n{env_info}", r"\x1b\[97mcolor-cli3\x1b\[0m, " rf"version \x1b\[32m{re.escape(__version__)}" r"\x1b\[0m\n" r"\x1b\[90m{'.+'}" r"\x1b\[0m\n", ), ( "{prog_name} v{version} - {package_name}", r"\x1b\[97mcolor-cli3\x1b\[0m " rf"v\x1b\[32m{re.escape(__version__)}" r"\x1b\[0m - " r"\x1b\[97mclick_extra" r"\x1b\[0m\n", ), ( "{prog_name}, version {version} (Python {env_info[python][version]})", r"\x1b\[97mcolor-cli3\x1b\[0m, " rf"version \x1b\[32m{re.escape(__version__)}\x1b\[0m " r"\(Python \x1b\[90m3\.\d+\.\d+ .+\x1b\[0m\)\n", ), ), ) def test_custom_message(invoke, cmd_decorator, message, regex_stdout): @cmd_decorator @extra_version_option(message=message) def color_cli3(): echo("It works!") result = invoke(color_cli3, "--version", color=True) assert result.exit_code == 0 assert not result.stderr assert re.fullmatch(regex_stdout, result.output)
[docs]@parametrize("cmd_decorator", command_decorators(no_groups=True)) def test_style_reset(invoke, cmd_decorator): @cmd_decorator @extra_version_option( message_style=None, version_style=None, prog_name_style=None, ) def color_reset(): pass result = invoke(color_reset, "--version", color=True) assert result.exit_code == 0 assert not result.stderr assert result.output == strip_ansi(result.output)
[docs]@skip_windows_colors @parametrize("cmd_decorator", command_decorators(no_groups=True)) def test_custom_message_style(invoke, cmd_decorator): @cmd_decorator @extra_version_option( message="{prog_name} v{version} - {package_name} (latest)", message_style=Style(fg="cyan"), prog_name_style=Style(fg="green", bold=True), version_style=Style(fg="bright_yellow", bg="red"), package_name_style=Style(fg="bright_blue", italic=True), ) def custom_style(): pass result = invoke(custom_style, "--version", color=True) assert result.exit_code == 0 assert not result.stderr assert result.output == ( "\x1b[32m\x1b[1mcustom-style\x1b[0m\x1b[36m " f"v\x1b[0m\x1b[93m\x1b[41m{__version__}\x1b[0m\x1b[36m - " "\x1b[0m\x1b[94m\x1b[3mclick_extra\x1b[0m\x1b[36m (latest)\x1b[0m\n" )
[docs]@parametrize("cmd_decorator", command_decorators(no_groups=True)) def test_context_meta(invoke, cmd_decorator): @cmd_decorator @extra_version_option @pass_context def version_metadata(ctx): for field in ExtraVersionOption.template_fields: value = ctx.meta[f"click_extra.{field}"] echo(f"{field} = {value}") result = invoke(version_metadata, color=True) assert result.exit_code == 0 assert not result.stderr assert re.fullmatch( ( r"module = <module 'click_extra\.testing' from '.+testing\.py'>\n" r"module_name = click_extra\.testing\n" r"module_file = .+testing\.py\n" rf"module_version = None\n" r"package_name = click_extra\n" rf"package_version = {__version__}\n" r"exec_name = click_extra\.testing\n" rf"version = {__version__}\n" r"prog_name = version-metadata\n" r"env_info = {'.+'}\n" ), result.output, ) assert result.output == strip_ansi(result.output)
[docs]@skip_windows_colors @pytest.mark.parametrize( "params", (None, "--help", "blah", ("--config", "random.toml")), ) def test_integrated_version_option_precedence(invoke, params): @extra_group(version="1.2.3.4") def color_cli4(): echo("It works!") result = invoke(color_cli4, "--version", params, color=True) assert result.exit_code == 0 assert not result.stderr assert result.stdout == ( "\x1b[97mcolor-cli4\x1b[0m, version \x1b[32m1.2.3.4\x1b[0m\n" )
[docs]@skip_windows_colors def test_color_option_precedence(invoke): """--no-color has an effect on --version, if placed in the right order. Eager parameters are evaluated in the order as they were provided on the command line by the user as expleined in: https://click.palletsprojects.com/en/8.0.x/advanced/#callback-evaluation-order .. todo:: Maybe have the possibility to tweak CLI callback evaluation order so we can let the user to have the NO_COLOR env set to allow for color-less ``--version`` output. """ @click.command @color_option @extra_version_option(version="2.1.9") def color_cli6(): echo(Style(fg="yellow")("It works!")) result = invoke(color_cli6, "--no-color", "--version", "command1", color=True) assert result.exit_code == 0 assert not result.stderr assert result.stdout == "color-cli6, version 2.1.9\n" result = invoke(color_cli6, "--version", "--no-color", "command1", color=True) assert result.exit_code == 0 assert not result.stderr assert result.stdout == ( "\x1b[97mcolor-cli6\x1b[0m, version \x1b[32m2.1.9\x1b[0m\n" )