summaryrefslogtreecommitdiff
path: root/tests/testutils/test_functional_testutils.py
blob: d1047c8ee1ec8b96c9ebb588eeb11c79d14e69e1 (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
# 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

"""Tests for the functional test framework."""

from pathlib import Path
from unittest.mock import MagicMock

import pytest
from _pytest.outcomes import Skipped

from pylint import testutils
from pylint.testutils.functional import (
    FunctionalTestFile,
    get_functional_test_files_from_directory,
)

HERE = Path(__file__).parent
DATA_DIRECTORY = HERE / "data"


@pytest.fixture(name="pytest_config")
def pytest_config_fixture() -> MagicMock:
    def _mock_getoption(option: str) -> bool:
        if option == "minimal_messages_config":
            return True
        return False

    config = MagicMock()
    config.getoption.side_effect = _mock_getoption
    return config


def test_parsing_of_pylintrc_init_hook() -> None:
    """Test that we correctly parse an init-hook in a settings file."""
    with pytest.raises(RuntimeError):
        test_file = FunctionalTestFile(str(DATA_DIRECTORY), "init_hook.py")
        testutils.LintModuleTest(test_file)


def test_get_functional_test_files_from_directory() -> None:
    """Test that we correctly check the functional test directory structures."""
    with pytest.raises(AssertionError) as exc_info:
        get_functional_test_files_from_directory(DATA_DIRECTORY / "u")
    assert exc_info.match("'use_dir.py' should go in 'use'")
    assert exc_info.match(
        "using_dir.py should go in a directory that starts with the "
        "first letters of 'using_dir'"
    )
    assert "incredibly_bold_mischief.py" not in str(exc_info.value)
    # Leading underscore mean that this should not fail the assertion
    get_functional_test_files_from_directory(DATA_DIRECTORY / "u/_no_issue_here")


def test_get_functional_test_files_from_crowded_directory() -> None:
    """Test that we correctly check the functional test directory structures."""
    with pytest.raises(AssertionError) as exc_info:
        get_functional_test_files_from_directory(
            DATA_DIRECTORY / "m", max_file_per_directory=1
        )
    assert exc_info.match("m: 4 when the max is 1")
    assert exc_info.match("max_overflow: 3 when the max is 1")
    with pytest.raises(AssertionError) as exc_info:
        get_functional_test_files_from_directory(
            DATA_DIRECTORY / "m", max_file_per_directory=3
        )
    assert exc_info.match("m: 4 when the max is 3")
    assert "max_overflow" not in str(exc_info.value)


def test_minimal_messages_config_enabled(pytest_config: MagicMock) -> None:
    """Test that all messages not targeted in the functional test are disabled
    when running with --minimal-messages-config.
    """
    test_file = FunctionalTestFile(
        str(DATA_DIRECTORY / "m"), "minimal_messages_config.py"
    )
    mod_test = testutils.LintModuleTest(test_file, pytest_config)
    assert all(
        mod_test._linter.is_message_enabled(msgid)
        for msgid in (
            "consider-using-with",
            "unspecified-encoding",
            "consider-using-f-string",
            # Always enable fatal errors: important not to have false negatives
            "astroid-error",
            "fatal",
            "syntax-error",
        )
    )
    assert not mod_test._linter.is_message_enabled("unused-import")


def test_minimal_messages_config_excluded_file(pytest_config: MagicMock) -> None:
    """Test that functional test files can be excluded from the run with
    --minimal-messages-config if they set the exclude_from_minimal_messages_config
    option in their rcfile.
    """
    test_file = FunctionalTestFile(
        str(DATA_DIRECTORY / "m"), "minimal_messages_excluded.py"
    )
    mod_test = testutils.LintModuleTest(test_file, pytest_config)
    with pytest.raises(Skipped):
        mod_test.setUp()