| # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
| # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE |
| # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt |
| |
| """Test the primer commands.""" |
| from __future__ import annotations |
| |
| import sys |
| from pathlib import Path |
| from unittest.mock import patch |
| |
| import pytest |
| from _pytest.capture import CaptureFixture |
| |
| from pylint.constants import IS_PYPY |
| from pylint.testutils._primer.primer import Primer |
| |
| HERE = Path(__file__).parent |
| TEST_DIR_ROOT = HERE.parent.parent |
| PRIMER_DIRECTORY = TEST_DIR_ROOT / ".pylint_primer_tests/" |
| PACKAGES_TO_PRIME_PATH = TEST_DIR_ROOT / "primer/packages_to_prime.json" |
| FIXTURES_PATH = HERE / "fixtures" |
| |
| PRIMER_CURRENT_INTERPRETER = (3, 11) |
| |
| DEFAULT_ARGS = ["python tests/primer/__main__.py", "compare", "--commit=v2.14.2"] |
| |
| |
| @pytest.mark.parametrize("args", [[], ["wrong_command"]]) |
| def test_primer_launch_bad_args(args: list[str], capsys: CaptureFixture) -> None: |
| with pytest.raises(SystemExit): |
| with patch("sys.argv", ["python tests/primer/__main__.py", *args]): |
| Primer(PRIMER_DIRECTORY, PACKAGES_TO_PRIME_PATH).run() |
| out, err = capsys.readouterr() |
| assert not out |
| assert "usage: Pylint Primer" in err |
| |
| |
| @pytest.mark.skipif( |
| sys.version_info[:2] != PRIMER_CURRENT_INTERPRETER or IS_PYPY, |
| reason=( |
| "Primers are internal and will always be run for only one interpreter (currently" |
| f" {PRIMER_CURRENT_INTERPRETER})" |
| ), |
| ) |
| class TestPrimer: |
| @pytest.mark.parametrize( |
| "directory", |
| [ |
| pytest.param(p, id=str(p.relative_to(FIXTURES_PATH))) |
| for p in FIXTURES_PATH.iterdir() |
| if p.is_dir() and p.name != "batched" # tested separately |
| ], |
| ) |
| def test_compare(self, directory: Path) -> None: |
| """Test for the standard case. |
| |
| Directory in 'fixtures/' with 'main.json', 'pr.json' and 'expected.txt'. |
| """ |
| self.__assert_expected(directory) |
| |
| def test_compare_batched(self) -> None: |
| fixture = FIXTURES_PATH / "batched" |
| self.__assert_expected( |
| fixture, |
| fixture / "main_BATCHIDX.json", |
| fixture / "pr_BATCHIDX.json", |
| batches=2, |
| ) |
| |
| def test_truncated_compare(self) -> None: |
| """Test for the truncation of comments that are too long.""" |
| max_comment_length = 525 |
| directory = FIXTURES_PATH / "message_changed" |
| with patch( |
| "pylint.testutils._primer.primer_compare_command.MAX_GITHUB_COMMENT_LENGTH", |
| max_comment_length, |
| ): |
| content = self.__assert_expected( |
| directory, expected_file=directory / "expected_truncated.txt" |
| ) |
| assert len(content) < max_comment_length |
| |
| @staticmethod |
| def __assert_expected( |
| directory: Path, |
| main: Path | None = None, |
| pr: Path | None = None, |
| expected_file: Path | None = None, |
| batches: int = 0, |
| ) -> str: |
| if main is None: |
| main = directory / "main.json" |
| if pr is None: |
| pr = directory / "pr.json" |
| if expected_file is None: |
| expected_file = directory / "expected.txt" |
| new_argv = [*DEFAULT_ARGS, f"--base-file={main}", f"--new-file={pr}"] |
| if batches: |
| new_argv.append(f"--batches={batches}") |
| with patch("sys.argv", new_argv): |
| Primer(PRIMER_DIRECTORY, PACKAGES_TO_PRIME_PATH).run() |
| with open(PRIMER_DIRECTORY / "comment.txt", encoding="utf8") as f: |
| content = f.read() |
| with open(expected_file, encoding="utf8") as f: |
| expected = f.read() |
| # rstrip so the expected.txt can end with a newline |
| assert content == expected.rstrip("\n") |
| return content |