Skip to content

Commit

Permalink
🧪 cli tests
Browse files Browse the repository at this point in the history
  • Loading branch information
juftin committed Jan 18, 2024
1 parent 13c7604 commit 9912572
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 9 deletions.
15 changes: 8 additions & 7 deletions hatch_pip_compile/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
import json
import os
import subprocess
from typing import Any, Self, Sequence
from typing import Any, Sequence

import click
import rich.traceback

from hatch_pip_compile.__about__ import __application__, __version__


@dataclasses.dataclass
class _HatchCommandRunner:
class HatchCommandRunner:
"""
Hatch Command Runner
"""
Expand Down Expand Up @@ -45,8 +47,6 @@ def __post_init__(self):
raise click.BadParameter(msg)
elif self.upgrade_all:
self.environments = list(self.supported_environments)
elif isinstance(self.environments, str):
self.environments = [self.environments]
unsupported_environments = set(self.environments).difference(self.supported_environments)
if unsupported_environments:
msg = (
Expand All @@ -56,7 +56,7 @@ def __post_init__(self):
)
raise click.BadParameter(msg)

def __enter__(self) -> Self:
def __enter__(self) -> HatchCommandRunner:
"""
Set the environment variables
"""
Expand Down Expand Up @@ -113,7 +113,7 @@ def hatch_cli(self):
capture_output=True,
check=False,
)
if result.returncode != 0:
if result.returncode != 0: # pragma: no cover
self.console.print(
"[bold yellow]hatch command[/bold yellow]: "
f"[bold blue]`{' '.join(environment_command)}`[/bold blue]"
Expand Down Expand Up @@ -146,6 +146,7 @@ def _get_supported_environments(cls) -> set[str]:


@click.command("hatch-pip-compile")
@click.version_option(version=__version__, prog_name=__application__)
@click.argument("environment", default=None, type=click.STRING, required=False, nargs=-1)
@click.option(
"-U",
Expand Down Expand Up @@ -179,7 +180,7 @@ def cli(
Upgrade your `hatch-pip-compile` managed dependencies
from the command line.
"""
with _HatchCommandRunner(
with HatchCommandRunner(
environments=environment,
upgrade=upgrade,
upgrade_packages=upgrade_packages,
Expand Down
12 changes: 10 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ show_missing = true
branch = true
omit = [
"hatch_pip_compile/__about__.py",
"hatch_pip_compile/hooks.py"
"hatch_pip_compile/hooks.py",
"hatch_pip_compile/__main__.py"
]
parallel = true
source_pkgs = ["hatch_pip_compile", "tests"]
Expand All @@ -78,6 +79,10 @@ post-install-commands = [
python = "3.11"
type = "pip-compile"

[tool.hatch.envs.default.scripts]
cov = "hatch run test:cov {args:}"
test = "hatch run test:test {args:}"

[tool.hatch.envs.docs]
detached = false
type = "pip-compile"
Expand All @@ -86,7 +91,7 @@ type = "pip-compile"
detached = true

[tool.hatch.envs.gen.scripts]
lock-all = "hatch env run --env default -- python -m hatch_pip_compile --all --verbose {args:}"
lock-all = "hatch env run --env default -- python -m hatch_pip_compile --all {args:}"
release = [
"npm install --prefix .github/semantic_release/",
"npx --prefix .github/semantic_release/ semantic-release {args:}"
Expand Down Expand Up @@ -139,6 +144,9 @@ dependencies = [
cov = [
"pytest --cov-config=pyproject.toml --cov {args: tests/ -v}"
]
test = [
"pytest {args: tests/ -v}"
]

[tool.hatch.envs.versions]
dependencies = []
Expand Down
23 changes: 23 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Shared fixtures for tests.
"""

import contextlib
import os
import pathlib
import shutil
Expand Down Expand Up @@ -32,6 +33,16 @@ def mock_check_command() -> Generator[patch, None, None]:
yield mock


@pytest.fixture
def subprocess_run() -> Generator[patch, None, None]:
"""
Disable the `subprocess.run` for testing
"""
with patch("subprocess.run") as mock:
mock.return_value = CompletedProcess(args=[], returncode=0, stdout=b"", stderr=b"")
yield mock


@pytest.fixture
def platform() -> Platform:
"""
Expand Down Expand Up @@ -132,6 +143,18 @@ def update_pyproject(self) -> None:
"""
tomlkit.dump(self.toml_doc, self.pyproject.open("w"))

@contextlib.contextmanager
def chdir(self) -> Generator[None, None, None]:
"""
Change the working directory to the isolation
"""
current_dir = os.getcwd()
try:
os.chdir(self.isolation)
yield
finally:
os.chdir(current_dir)


@pytest.fixture
def pip_compile(
Expand Down
174 changes: 174 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
"""
Testing the hatch-pip-compile CLI
"""

from unittest.mock import Mock

import click
import pytest
from click.testing import CliRunner

from hatch_pip_compile import __version__
from hatch_pip_compile.cli import HatchCommandRunner, cli
from tests.conftest import PipCompileFixture


def test_cli_help() -> None:
"""
Test the CLI with the --help flag
"""
runner = CliRunner()
result = runner.invoke(cli=cli, args=["--help"])
assert result.exit_code == 0


def test_cli_version() -> None:
"""
Test the CLI with the --version flag
"""
runner = CliRunner()
result = runner.invoke(cli=cli, args=["--version"])
assert result.exit_code == 0
assert f"hatch-pip-compile, version {__version__}" in result.output


def test_cli_no_args_mocked(pip_compile: PipCompileFixture, subprocess_run: Mock) -> None:
"""
Test the CLI with no arguments - mock the result
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
_ = runner.invoke(cli=cli)
assert subprocess_run.call_count == 1
subprocess_run.assert_called_once()
subprocess_run.assert_called_with(
args=["hatch", "env", "show", "--json"], capture_output=True, check=True
)


def test_cli_no_args(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with no arguments
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli)
assert result.exit_code == 0
assert "hatch-pip-compile: Targeting environments: default" in result.output
assert (
"hatch-pip-compile: Running `hatch env run --env default -- python --version`"
in result.output
)


def test_cli_bad_env(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with a non-existent environment
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["bad_env"])
assert result.exit_code != 0
assert "error" in result.output.lower()
assert (
"The following environments are not supported or unknown: bad_env. "
"Supported environments are: default, test"
) in result.output


def test_cli_test_env(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with the `test` argument
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["test"])
assert result.exit_code == 0
assert "hatch-pip-compile: Targeting environments: test" in result.output
assert (
"hatch-pip-compile: Running `hatch env run --env test -- python --version`"
in result.output
)


def test_cli_all(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with the `--all` argument
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["--all"])
assert result.exit_code == 0
assert "hatch-pip-compile: Targeting environments: default, test" in result.output


def test_cli_upgrade(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with the `--upgrade` argument
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["--upgrade"])
assert result.exit_code == 0
assert "hatch-pip-compile: Upgrading all dependencies" in result.output


def test_cli_upgrade_packages(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with the `--upgrade-package` argument
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["--upgrade-package", "requests"])
assert result.exit_code == 0
assert "hatch-pip-compile: Upgrading packages: requests" in result.output


def test_cli_upgrade_test(pip_compile: PipCompileFixture) -> None:
"""
Test the full CLI with the `--upgrade` argument for the `test` environment
"""
runner = CliRunner()
with runner.isolated_filesystem(temp_dir=pip_compile.isolation):
result = runner.invoke(cli=cli, args=["test", "--upgrade"])
assert result.exit_code == 0
assert "hatch-pip-compile: Upgrading all dependencies" in result.output
assert "hatch-pip-compile: Targeting environments: test" in result.output


def test_command_runner_supported_environments(
monkeypatch: pytest.MonkeyPatch,
pip_compile: PipCompileFixture,
) -> None:
"""
Test the `supported_environments` attribute
"""
with pip_compile.chdir():
command_runner = HatchCommandRunner(
environments=["test"],
upgrade=True,
upgrade_packages=[],
)
assert command_runner.supported_environments == {"default", "test"}


def test_command_runner_non_supported_environments(
monkeypatch: pytest.MonkeyPatch,
pip_compile: PipCompileFixture,
) -> None:
"""
Test that a bad environment raises a `BadParameter` exception
"""
with pip_compile.chdir():
with pytest.raises(
click.BadParameter,
match=(
"The following environments are not supported or unknown: bad_env. "
"Supported environments are: default, test"
),
):
_ = HatchCommandRunner(
environments=["bad_env"],
upgrade=True,
upgrade_packages=[],
)

0 comments on commit 9912572

Please sign in to comment.