From 6bf34a4e0034310f8210257649a722b861f4ed8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saugat=20Pachhai=20=28=E0=A4=B8=E0=A5=8C=E0=A4=97=E0=A4=BE?= =?UTF-8?q?=E0=A4=A4=29?= Date: Thu, 3 Aug 2023 23:12:38 +0545 Subject: [PATCH] completion: fix broken completion generation for zsh `dvc commit --help` was also completely broken, which is also fixed. This adds unit tests for completion generation for both zsh/bash, and tests that --help works for all commands. --- dvc/commands/commit.py | 4 +-- dvc/commands/completion.py | 5 ++- tests/unit/command/test_completion.py | 17 ++++++++++ tests/unit/command/test_help.py | 48 +++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 tests/unit/command/test_completion.py create mode 100644 tests/unit/command/test_help.py diff --git a/dvc/commands/commit.py b/dvc/commands/commit.py index e8c9e98878..21c53ea7da 100644 --- a/dvc/commands/commit.py +++ b/dvc/commands/commit.py @@ -48,8 +48,8 @@ def add_parser(subparsers, parent_parser): action="store_true", default=False, help=( - "Commit data even if hash values for dependencies or", - "outputs did not change.", + "Commit data even if hash values for dependencies or " + "outputs did not change." ), ) commit_parser.add_argument( diff --git a/dvc/commands/completion.py b/dvc/commands/completion.py index 9f2182ecab..ac2dc0721b 100644 --- a/dvc/commands/completion.py +++ b/dvc/commands/completion.py @@ -9,6 +9,9 @@ logger = logging.getLogger(__name__) +SUPPORTED_SHELLS = ["bash", "zsh"] + + class CmdCompletion(CmdBaseNoRepo): def run(self): import shtab @@ -35,6 +38,6 @@ def add_parser(subparsers, parent_parser): "--shell", help="Shell syntax for completions.", default="bash", - choices=["bash", "zsh"], + choices=SUPPORTED_SHELLS, ) completion_parser.set_defaults(func=CmdCompletion) diff --git a/tests/unit/command/test_completion.py b/tests/unit/command/test_completion.py new file mode 100644 index 0000000000..926c67f1e6 --- /dev/null +++ b/tests/unit/command/test_completion.py @@ -0,0 +1,17 @@ +import logging + +import pytest + +from dvc.cli import main +from dvc.commands.completion import SUPPORTED_SHELLS + + +@pytest.mark.parametrize("shell", SUPPORTED_SHELLS) +def test_completion(caplog, capsys, shell): + with caplog.at_level(logging.INFO): + assert main(["completion", "-s", shell]) == 0 + assert not caplog.text + + out, err = capsys.readouterr() + assert not err + assert out diff --git a/tests/unit/command/test_help.py b/tests/unit/command/test_help.py new file mode 100644 index 0000000000..f03cbb2463 --- /dev/null +++ b/tests/unit/command/test_help.py @@ -0,0 +1,48 @@ +import logging +from argparse import SUPPRESS, ArgumentParser +from typing import Tuple + +import pytest +import shtab + +from dvc.cli import main +from dvc.cli.parser import get_main_parser + + +def command_tuples(): + root: Tuple[str, ...] = () + commands = [root] + + def recurse_parser(parser: ArgumentParser, parents: Tuple[str, ...] = root) -> None: + for positional in parser._get_positional_actions(): + if positional.help != SUPPRESS and isinstance(positional.choices, dict): + public_cmds = shtab.get_public_subcommands(positional) + for subcmd, subparser in positional.choices.items(): + cmd = (*parents, subcmd) + if subcmd in public_cmds: + commands.append(cmd) + recurse_parser(subparser, cmd) + + main_parser = get_main_parser() + recurse_parser(main_parser) + return sorted(commands) + + +def pytest_generate_tests(metafunc): + def ids(values): + if values: + return "-".join(values) + return "dvc" + + metafunc.parametrize("command_tuples", command_tuples(), ids=ids) + + +def test_help(caplog, capsys, command_tuples): + with caplog.at_level(logging.INFO), pytest.raises(SystemExit) as e: + main([*command_tuples, "--help"]) + assert e.value.code == 0 + assert not caplog.text + + out, err = capsys.readouterr() + assert not err + assert out