summaryrefslogtreecommitdiff
path: root/tests/conftest.py
blob: 40b138448d8012a812322d911f6a26da2dd3d28d (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# 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

# pylint: disable=redefined-outer-name

from __future__ import annotations

import os
from collections.abc import Callable
from pathlib import Path

import pytest

from pylint import checkers
from pylint.checkers import BaseChecker
from pylint.lint import PyLinter
from pylint.lint.run import _cpu_count
from pylint.reporters import BaseReporter
from pylint.testutils import MinimalTestReporter

HERE = Path(__file__).parent


@pytest.fixture()
def tests_directory() -> Path:
    return HERE


@pytest.fixture
def linter(
    checker: type[BaseChecker] | None,
    register: Callable[[PyLinter], None] | None,
    enable: str | None,
    disable: str | None,
    reporter: type[BaseReporter],
) -> PyLinter:
    _linter = PyLinter()
    _linter.set_reporter(reporter())
    checkers.initialize(_linter)
    if register:
        register(_linter)
    if checker:
        _linter.register_checker(checker(_linter))
    if disable:
        for msg in disable:
            _linter.disable(msg)
    if enable:
        for msg in enable:
            _linter.enable(msg)
    os.environ.pop("PYLINTRC", None)
    return _linter


@pytest.fixture(scope="module")
def checker() -> None:
    return None


@pytest.fixture(scope="module")
def register() -> None:
    return None


@pytest.fixture(scope="module")
def enable() -> None:
    return None


@pytest.fixture(scope="module")
def disable() -> None:
    return None


@pytest.fixture(scope="module")
def reporter() -> type[MinimalTestReporter]:
    return MinimalTestReporter


def pytest_addoption(parser: pytest.Parser) -> None:
    parser.addoption(
        "--primer-stdlib",
        action="store_true",
        default=False,
        help="Run primer stdlib tests",
    )
    parser.addoption(
        "--primer-external",
        action="store_true",
        default=False,
        help="Run primer external tests",
    )
    parser.addoption(
        "--minimal-messages-config",
        action="store_true",
        default=False,
        help=(
            "Disable all messages that are not explicitly expected when running functional tests. "
            "This is useful for finding problems with the @only_required_for_messages / @check_messages "
            "decorator, but can also produce false negatives if a functional test file only tests for "
            "false positive of messages and thus does not declare which messages are expected."
        ),
    )


def pytest_collection_modifyitems(
    config: pytest.Config, items: list[pytest.Function]
) -> None:
    """Convert command line options to markers."""
    # Add skip_primer_external mark
    if not config.getoption("--primer-external"):
        skip_primer_external = pytest.mark.skip(
            reason="need --primer-external option to run"
        )
        for item in items:
            if "primer_external_batch_one" in item.keywords:
                item.add_marker(skip_primer_external)

    # Add skip_primer_stdlib mark
    if not config.getoption("--primer-stdlib"):
        skip_primer_stdlib = pytest.mark.skip(
            reason="need --primer-stdlib option to run"
        )
        for item in items:
            if "primer_stdlib" in item.keywords:
                item.add_marker(skip_primer_stdlib)

    # Add skip_cpu_cores mark
    if _cpu_count() < 2:
        skip_cpu_cores = pytest.mark.skip(
            reason="Need 2 or more cores for test to be meaningful"
        )
        for item in items:
            if "needs_two_cores" in item.keywords:
                item.add_marker(skip_cpu_cores)