Skip to content

Commit 7e12334

Browse files
committed
test_handle_force_color_no_color
1 parent b5b91c1 commit 7e12334

File tree

1 file changed

+150
-1
lines changed

1 file changed

+150
-1
lines changed

tests/lint/test_pylinter.py

Lines changed: 150 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,36 @@
22
# For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE
33
# Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt
44

5+
from __future__ import annotations
6+
7+
import io
58
import os
9+
import sys
10+
import warnings
611
from pathlib import Path
712
from typing import Any, NoReturn
813
from unittest import mock
914
from unittest.mock import patch
1015

16+
import pytest
1117
from pytest import CaptureFixture
1218

13-
from pylint.lint.pylinter import MANAGER, PyLinter
19+
from pylint.lint.pylinter import (
20+
FORCE_COLOR,
21+
MANAGER,
22+
NO_COLOR,
23+
PY_COLORS,
24+
WARN_BOTH_COLOR_SET,
25+
PyLinter,
26+
_handle_force_color_no_color,
27+
)
28+
from pylint.reporters.text import ColorizedTextReporter, TextReporter
1429
from pylint.utils import FileState
1530

31+
COLORIZED_REPORTERS = "colorized_reporters"
32+
TEXT_REPORTERS = "text_reporters"
33+
STDOUT_TEXT = "stdout"
34+
1635

1736
def raise_exception(*args: Any, **kwargs: Any) -> NoReturn:
1837
raise ValueError
@@ -68,3 +87,133 @@ def test_open_pylinter_prefer_stubs(linter: PyLinter) -> None:
6887
assert MANAGER.prefer_stubs
6988
finally:
7089
MANAGER.prefer_stubs = False
90+
91+
92+
def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
93+
if metafunc.function.__name__ != test_handle_force_color_no_color.__name__:
94+
return
95+
96+
if (
97+
TEXT_REPORTERS not in metafunc.fixturenames
98+
or COLORIZED_REPORTERS not in metafunc.fixturenames
99+
):
100+
warnings.warn(
101+
f"Missing fixture {TEXT_REPORTERS} or {COLORIZED_REPORTERS} in"
102+
f" {test_handle_force_color_no_color.function.__name__}??",
103+
stacklevel=2,
104+
)
105+
return
106+
107+
parameters = []
108+
109+
reporter_combinations = [
110+
("file", STDOUT_TEXT),
111+
("file",),
112+
(STDOUT_TEXT,),
113+
("",),
114+
]
115+
116+
for tr in list(reporter_combinations):
117+
for cr in list(reporter_combinations):
118+
tr = tuple(t for t in tr if t)
119+
cr = tuple(t for t in cr if t)
120+
121+
total_reporters = len(tr) + len(cr)
122+
unique_reporters = len(set(tr + cr))
123+
124+
if total_reporters == 0:
125+
continue
126+
127+
if unique_reporters != total_reporters:
128+
continue
129+
130+
parameters.append((tuple(tr), tuple(cr)))
131+
132+
metafunc.parametrize(
133+
f"{TEXT_REPORTERS}, {COLORIZED_REPORTERS}", parameters, ids=repr
134+
)
135+
136+
137+
@pytest.mark.parametrize(
138+
"no_color",
139+
[True, False],
140+
ids=lambda no_color: f"{no_color=}",
141+
)
142+
@pytest.mark.parametrize(
143+
"py_colors",
144+
[True, False],
145+
ids=lambda py_colors: f"{py_colors=}",
146+
)
147+
@pytest.mark.parametrize(
148+
"force_color",
149+
[True, False],
150+
ids=lambda force_color: f"{force_color=}",
151+
)
152+
def test_handle_force_color_no_color(
153+
monkeypatch: pytest.MonkeyPatch,
154+
recwarn: pytest.WarningsRecorder,
155+
no_color: bool,
156+
py_colors: bool,
157+
force_color: bool,
158+
text_reporters: tuple[str],
159+
colorized_reporters: tuple[str],
160+
) -> None:
161+
monkeypatch.setenv(NO_COLOR, "1" if no_color else "")
162+
monkeypatch.setenv(FORCE_COLOR, "1" if force_color else "")
163+
monkeypatch.setenv(PY_COLORS, "1" if py_colors else "")
164+
165+
force_color = force_color or py_colors
166+
167+
if STDOUT_TEXT in text_reporters or STDOUT_TEXT in colorized_reporters:
168+
monkeypatch.setattr(sys, STDOUT_TEXT, io.TextIOWrapper(io.BytesIO()))
169+
170+
reporters = []
171+
for reporter, group in (
172+
(TextReporter, text_reporters),
173+
(ColorizedTextReporter, colorized_reporters),
174+
):
175+
for name in group:
176+
if name == STDOUT_TEXT:
177+
reporters.append(reporter())
178+
if name == "file":
179+
reporters.append(reporter(io.TextIOWrapper(io.BytesIO())))
180+
181+
_handle_force_color_no_color(reporters)
182+
183+
if no_color and force_color:
184+
# Both NO_COLOR and FORCE_COLOR are set; expecting a warning.
185+
both_color_warning = [
186+
idx
187+
for idx, w in enumerate(recwarn.list)
188+
if WARN_BOTH_COLOR_SET in str(w.message)
189+
]
190+
assert len(both_color_warning) == 1
191+
recwarn.list.pop(both_color_warning[0])
192+
193+
if no_color:
194+
# No ColorizedTextReporter expected to be connected to stdout.
195+
assert all(
196+
not isinstance(rep, ColorizedTextReporter)
197+
for rep in reporters
198+
if rep.out.buffer is sys.stdout.buffer
199+
)
200+
201+
if STDOUT_TEXT in colorized_reporters:
202+
assert len(recwarn.list) == 1 # expect a warning for overriding stdout
203+
else:
204+
assert len(recwarn.list) == 0 # no warning expected
205+
elif force_color:
206+
# No TextReporter expected to be connected to stdout.
207+
# pylint: disable=unidiomatic-typecheck # Want explicit type check.
208+
assert all(
209+
type(rep) is not TextReporter
210+
for rep in reporters
211+
if rep.out.buffer is sys.stdout.buffer
212+
)
213+
214+
if STDOUT_TEXT in text_reporters:
215+
assert len(recwarn.list) == 1 # expect a warning for overriding stdout
216+
else:
217+
assert len(recwarn.list) == 0 # no warning expected
218+
else:
219+
assert len(recwarn.list) == 0 # no warning expected

0 commit comments

Comments
 (0)