Skip to content

Commit

Permalink
Merge pull request #9 from realshouzy/improve-tests
Browse files Browse the repository at this point in the history
Improve tests
  • Loading branch information
realshouzy authored Jun 7, 2024
2 parents 82ff5f4 + 2c4b3a5 commit 42bbbb7
Show file tree
Hide file tree
Showing 2 changed files with 223 additions and 14 deletions.
154 changes: 145 additions & 9 deletions tests/pip_purge_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import argparse
import importlib.metadata
import logging
import sys
from pathlib import Path
from types import SimpleNamespace
Expand Down Expand Up @@ -51,6 +52,11 @@ def test_constants(
assert constant == expected


def test_default_settings_pip_purge_logger() -> None:
assert pip_purge._logger.name == "pip-purge"
assert len(pip_purge._logger.handlers) == 2


def test_parse_args_empty_args() -> None:
assert pip_purge._parse_args([]) == (
argparse.Namespace(
Expand Down Expand Up @@ -404,45 +410,122 @@ def test_read_requirements(tmp_path: Path) -> None:
]


@pytest.mark.parametrize("arg", ["--verbose", "-v"])
def test_main_verbose_flag_sets_logger_level_to_debug(
dummy_dependencies: list[SimpleNamespace],
arg: str,
) -> None:
with mock.patch(
"importlib.metadata.distribution",
side_effect=lambda package: _custom_importlib_metadata_distribution(
package,
dummy_dependencies,
),
), mock.patch(
"importlib.metadata.distributions",
return_value=dummy_dependencies,
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main(["package_a", arg])
assert pip_purge._logger.level == logging.DEBUG
mock_subprocess_call.assert_called_once_with(
[*PIP_CMD, "uninstall", "package_a", "package_b", "package_e"],
stdout=sys.stdout,
stderr=sys.stderr,
)
assert exit_code == 0


def test_main_no_verbose_flag_sets_logger_level_to_info(
dummy_dependencies: list[SimpleNamespace],
) -> None:
with mock.patch(
"importlib.metadata.distribution",
side_effect=lambda package: _custom_importlib_metadata_distribution(
package,
dummy_dependencies,
),
), mock.patch(
"importlib.metadata.distributions",
return_value=dummy_dependencies,
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main(["package_a"])
assert pip_purge._logger.level == logging.INFO
mock_subprocess_call.assert_called_once_with(
[*PIP_CMD, "uninstall", "package_a", "package_b", "package_e"],
stdout=sys.stdout,
stderr=sys.stderr,
)
assert exit_code == 0


def test_main_error_exit_when_no_packages_provided(
caplog: pytest.LogCaptureFixture,
) -> None:
with mock.patch("importlib.metadata.distribution"), mock.patch(
with mock.patch(
"importlib.metadata.distribution",
), mock.patch(
"importlib.metadata.distributions",
):
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main([])
assert caplog.record_tuples == [("pip-purge", 40, "No packages provided")]
mock_subprocess_call.assert_not_called()
assert exit_code == 1


def test_main_warn_about_unrecognized_args_before_error_exit_when_no_packages_provided(
caplog: pytest.LogCaptureFixture,
) -> None:
with mock.patch("importlib.metadata.distribution"), mock.patch(
with mock.patch(
"importlib.metadata.distribution",
), mock.patch(
"importlib.metadata.distributions",
):
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main(["-v", "-a", "-b", "-y"])
assert (
"pip-purge",
30,
"Unrecognized arguments: '-a', '-b'",
) in caplog.record_tuples
assert ("pip-purge", 40, "No packages provided") in caplog.record_tuples
mock_subprocess_call.assert_not_called()
assert exit_code == 1


def test_main_warn_about_unrecognized_args(caplog: pytest.LogCaptureFixture) -> None:
with mock.patch("importlib.metadata.distribution"), mock.patch(
def test_main_warn_about_unrecognized_args(
caplog: pytest.LogCaptureFixture,
dummy_dependencies: list[SimpleNamespace],
) -> None:
with mock.patch(
"importlib.metadata.distribution",
side_effect=lambda package: _custom_importlib_metadata_distribution(
package,
dummy_dependencies,
),
), mock.patch(
"importlib.metadata.distributions",
return_value=dummy_dependencies,
), mock.patch(
"subprocess.call",
):
) as mock_subprocess_call:
exit_code: int = pip_purge.main(["package_a", "-v", "-a", "-b", "-y"])
assert (
"pip-purge",
30,
"Unrecognized arguments: '-a', '-b'",
) in caplog.record_tuples
mock_subprocess_call.assert_called_once_with(
[*PIP_CMD, "uninstall", "-y", "package_a", "package_b", "package_e"],
stdout=sys.stdout,
stderr=sys.stderr,
)
assert exit_code == 0


Expand Down Expand Up @@ -623,9 +706,11 @@ def test_main_dry_run(
assert exit_code == 0


@pytest.mark.parametrize("arg", ["--continue-on-fail", "-C"])
def test_main_continue_on_fail(
caplog: pytest.LogCaptureFixture,
dummy_dependencies: list[SimpleNamespace],
arg: str,
) -> None:
with mock.patch(
"importlib.metadata.distribution",
Expand All @@ -640,7 +725,7 @@ def test_main_continue_on_fail(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main(
["package_a", "--continue-on-fail"],
["package_a", arg],
)
assert caplog.record_tuples == [
(
Expand Down Expand Up @@ -676,10 +761,12 @@ def test_main_continue_on_fail(
assert exit_code == 0


@pytest.mark.parametrize("arg", ["--freeze-file", "-f"])
def test_main_freeze_packages(
tmp_path: Path,
caplog: pytest.LogCaptureFixture,
dummy_dependencies: list[SimpleNamespace],
arg: str,
) -> None:
test_freeze_file: Path = tmp_path / "freeze.txt"
test_freeze_file.touch()
Expand All @@ -699,7 +786,7 @@ def test_main_freeze_packages(
[
"package_a",
"--freeze-purged-packages",
"--freeze-file",
arg,
str(test_freeze_file),
],
)
Expand Down Expand Up @@ -780,5 +867,54 @@ def test_main_ignore_extra(
assert exit_code == 0


@pytest.mark.parametrize("arg", ["--requirement", "-r"])
def test_main_requirement(
tmp_path: Path,
caplog: pytest.LogCaptureFixture,
dummy_dependencies: list[SimpleNamespace],
arg: str,
) -> None:
test_requirement_file: Path = tmp_path / "requirement.txt"
test_requirement_file.touch()
test_requirement_file.write_text("package_a", encoding="utf-8")
with mock.patch(
"importlib.metadata.distribution",
side_effect=lambda package: _custom_importlib_metadata_distribution(
package,
dummy_dependencies,
),
), mock.patch(
"importlib.metadata.distributions",
return_value=dummy_dependencies,
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_purge.main(
[
arg,
str(test_requirement_file),
],
)
assert caplog.record_tuples == [
(
"pip-purge",
20,
"The following packages will be uninstalled: "
"package_a, package_b, package_e",
),
(
"pip-purge",
20,
f"Running: '{' '.join(PIP_CMD)} uninstall package_a package_b package_e'",
),
]
mock_subprocess_call.assert_called_once_with(
[*PIP_CMD, "uninstall", "package_a", "package_b", "package_e"],
stdout=sys.stdout,
stderr=sys.stderr,
)
assert exit_code == 0


if __name__ == "__main__":
raise SystemExit(pytest.main())
83 changes: 78 additions & 5 deletions tests/pip_review_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import argparse
import logging
import sys
from pathlib import Path
from unittest import mock
Expand Down Expand Up @@ -55,6 +56,11 @@ def test_constants(
assert constant == expected


def test_default_settings_pip_review_logger() -> None:
assert pip_review._logger.name == "pip-review"
assert len(pip_review._logger.handlers) == 2


def test_parse_args_empty_args() -> None:
assert pip_review._parse_args([]) == (
argparse.Namespace(
Expand Down Expand Up @@ -407,6 +413,50 @@ def test_format_table_value_error_when_columns_are_not_the_same_length() -> None
pip_review._format_table(test_columns)


@pytest.mark.parametrize("arg", ["--verbose", "-v"])
def test_main_verbose_flag_sets_logger_level_to_debug(
sample_subprocess_output: bytes,
arg: str,
) -> None:
with mock.patch(
"subprocess.check_output",
return_value=sample_subprocess_output,
), mock.patch(
"pip_manage.pip_review._upgrade_prompter.ask",
return_value="a",
), mock.patch(
"os.getenv",
return_value=None,
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_review.main([arg])
assert pip_review._logger.level == logging.DEBUG
mock_subprocess_call.assert_not_called()
assert exit_code == 0


def test_main_no_verbose_flag_sets_logger_level_to_info(
sample_subprocess_output: bytes,
) -> None:
with mock.patch(
"subprocess.check_output",
return_value=sample_subprocess_output,
), mock.patch(
"pip_manage.pip_review._upgrade_prompter.ask",
return_value="a",
), mock.patch(
"os.getenv",
return_value=None,
), mock.patch(
"subprocess.call",
) as mock_subprocess_call:
exit_code: int = pip_review.main([])
assert pip_review._logger.level == logging.INFO
mock_subprocess_call.assert_not_called()
assert exit_code == 0


@pytest.mark.parametrize(
("args", "err_msg"),
[
Expand All @@ -427,22 +477,45 @@ def test_main_mutually_exclusive_args_error(
err_msg: str,
) -> None:
exit_code: int = pip_review.main(args)
assert ("pip-review", 40, err_msg) in caplog.record_tuples
assert caplog.record_tuples == [("pip-review", 40, err_msg)]
assert exit_code == 1


def test_main_warn_about_unrecognized_args(caplog: pytest.LogCaptureFixture) -> None:
with mock.patch("importlib.metadata.distribution"), mock.patch(
"importlib.metadata.distributions",
def test_main_warn_about_unrecognized_args(
caplog: pytest.LogCaptureFixture,
sample_subprocess_output: bytes,
) -> None:
with mock.patch(
"subprocess.check_output",
return_value=sample_subprocess_output,
), mock.patch(
"pip_manage.pip_review._upgrade_prompter.ask",
return_value="a",
), mock.patch(
"os.getenv",
return_value=None,
), mock.patch(
"subprocess.call",
):
) as mock_subprocess_call:
exit_code: int = pip_review.main(["-x", "-v", "-a"])

assert (
"pip-review",
30,
"Unrecognized arguments: '-x'",
) in caplog.record_tuples
expected_cmd: list[str] = [
*PIP_CMD,
"install",
"-U",
"test1",
"test2",
]
mock_subprocess_call.assert_called_once_with(
expected_cmd,
stdout=sys.stdout,
stderr=sys.stderr,
)
assert exit_code == 0


Expand Down

0 comments on commit 42bbbb7

Please sign in to comment.