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 940c5b2 commit 8439447
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 5 deletions.
11 changes: 7 additions & 4 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 @@ -56,7 +58,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 @@ -146,6 +148,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 +182,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
9 changes: 8 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,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 +90,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 +143,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
129 changes: 129 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""
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_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 8439447

Please sign in to comment.