summaryrefslogtreecommitdiff
path: root/tests/testutils/_primer/test_primer.py
blob: d57e98d213827dcc0df8da1623204d83a1fbcf39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/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, 10)

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()
        ],
    )
    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_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,
    ) -> 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}"]
        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