Skip to content

Commit c39bd81

Browse files
committed
Update changelog & clenaup tests
Add changelog and doc for `--color` Remove type annotations from cli parsing tests and simplify click.Context capturing.
1 parent 3ed4681 commit c39bd81

File tree

3 files changed

+39
-59
lines changed

3 files changed

+39
-59
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Unreleased
1717
``--disable-format``.
1818
- Fix the resolution of `$schema` dialect to format checker classes
1919
- Fix package dependency lower bounds, including setting ``jsonschema>=4.5.1``
20+
- Output colorization can now be controlled with
21+
``--color [never|always|auto]``. Thanks :user:`WillDaSilva`!
2022

2123
0.20.0
2224
------

docs/usage.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ Detailed helptext is always available interactively via
3131
* - ``-o [TEXT|JSON]``, ``--output-format [TEXT|JSON]``
3232
- Use this option to choose how the output is presented. Either as ``TEXT`` (the
3333
default) or ``JSON``, as in ``-o JSON``.
34+
* - ``--color [always|never|auto]``
35+
- Control colorization of output. ``auto`` (the default) autodetects if
36+
the output is a terminal. ``always`` and ``never`` enable and disable
37+
colorization.
3438
* - ``--traceback-mode [short|full]``
3539
- By default, when an error is encountered, ``check-jsonschema`` will pretty-print
3640
the error and exit. Use ``--traceback-mode full`` to request the full traceback

tests/unit/test_cli_parse.py

Lines changed: 33 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
from __future__ import annotations
22

3-
import typing as t
43
from unittest import mock
54

65
import click
76
import pytest
87
from click.testing import CliRunner
9-
from click.testing import Result as ClickResult
108

119
from check_jsonschema import main as cli_main
1210
from check_jsonschema.cli import ParseResult, SchemaLoadingMode
1311

1412

13+
class BoxedContext:
14+
ref = None
15+
16+
17+
@pytest.fixture
18+
def boxed_context():
19+
return BoxedContext()
20+
21+
1522
@pytest.fixture
1623
def mock_parse_result():
1724
args = ParseResult()
@@ -21,8 +28,11 @@ def mock_parse_result():
2128

2229

2330
@pytest.fixture(autouse=True)
24-
def mock_cli_exec():
25-
with mock.patch("check_jsonschema.cli.execute") as m:
31+
def mock_cli_exec(boxed_context):
32+
def get_ctx(*args):
33+
boxed_context.ref = click.get_current_context()
34+
35+
with mock.patch("check_jsonschema.cli.execute", side_effect=get_ctx) as m:
2636
yield m
2737

2838

@@ -31,28 +41,6 @@ def runner() -> CliRunner:
3141
return CliRunner(mix_stderr=False)
3242

3343

34-
def invoke_and_get_ctx(
35-
runner: CliRunner,
36-
cmd: click.Command,
37-
args: t.Sequence[str],
38-
) -> tuple[ClickResult, click.Context]:
39-
# There doesn't appear to be a good way to get the Click context used by a
40-
# test invocation, so we replace the invoke method with a wrapper that
41-
# calls `click.get_current_context` to extract the context object.
42-
43-
ctx = None
44-
45-
def extract_ctx(*args, **kwargs):
46-
nonlocal ctx
47-
ctx = click.get_current_context()
48-
return click.Command.invoke(*args, **kwargs)
49-
50-
with mock.patch("click.Command.invoke", extract_ctx):
51-
results = runner.invoke(cmd, args)
52-
53-
return results, ctx
54-
55-
5644
@pytest.mark.parametrize(
5745
"schemafile,builtin_schema,check_metaschema,expect_mode",
5846
[
@@ -78,34 +66,34 @@ def test_parse_result_set_schema(
7866
assert args.schema_path is None
7967

8068

81-
def test_requires_some_args(runner: CliRunner):
69+
def test_requires_some_args(runner):
8270
result = runner.invoke(cli_main, [])
8371
assert result.exit_code == 2
8472

8573

86-
def test_schemafile_and_instancefile(runner: CliRunner, mock_parse_result: ParseResult):
74+
def test_schemafile_and_instancefile(runner, mock_parse_result):
8775
runner.invoke(cli_main, ["--schemafile", "schema.json", "foo.json"])
8876
assert mock_parse_result.schema_mode == SchemaLoadingMode.filepath
8977
assert mock_parse_result.schema_path == "schema.json"
9078
assert mock_parse_result.instancefiles == ("foo.json",)
9179

9280

93-
def test_requires_at_least_one_instancefile(runner: CliRunner):
81+
def test_requires_at_least_one_instancefile(runner):
9482
result = runner.invoke(cli_main, ["--schemafile", "schema.json"])
9583
assert result.exit_code == 2
9684

9785

98-
def test_requires_schemafile(runner: CliRunner):
86+
def test_requires_schemafile(runner):
9987
result = runner.invoke(cli_main, ["foo.json"])
10088
assert result.exit_code == 2
10189

10290

103-
def test_no_cache_defaults_false(runner: CliRunner, mock_parse_result: ParseResult):
91+
def test_no_cache_defaults_false(runner, mock_parse_result):
10492
runner.invoke(cli_main, ["--schemafile", "schema.json", "foo.json"])
10593
assert mock_parse_result.disable_cache is False
10694

10795

108-
def test_no_cache_flag_is_true(runner: CliRunner, mock_parse_result: ParseResult):
96+
def test_no_cache_flag_is_true(runner, mock_parse_result):
10997
runner.invoke(cli_main, ["--schemafile", "schema.json", "foo.json", "--no-cache"])
11098
assert mock_parse_result.disable_cache is True
11199

@@ -142,7 +130,7 @@ def test_no_cache_flag_is_true(runner: CliRunner, mock_parse_result: ParseResult
142130
],
143131
],
144132
)
145-
def test_mutex_schema_opts(runner: CliRunner, cmd_args: list[str]):
133+
def test_mutex_schema_opts(runner, cmd_args):
146134
result = runner.invoke(cli_main, cmd_args)
147135
assert result.exit_code == 2
148136
assert "are mutually exclusive" in result.stderr
@@ -156,65 +144,51 @@ def test_mutex_schema_opts(runner: CliRunner, cmd_args: list[str]):
156144
["-h"],
157145
],
158146
)
159-
def test_supports_common_option(runner: CliRunner, cmd_args: list[str]):
147+
def test_supports_common_option(runner, cmd_args):
160148
result = runner.invoke(cli_main, cmd_args)
161149
assert result.exit_code == 0
162150

163151

164152
@pytest.mark.parametrize(
165153
"setting,expect_value", [(None, None), ("1", False), ("0", False)]
166154
)
167-
def test_no_color_env_var(
168-
runner: CliRunner,
169-
monkeypatch: pytest.MonkeyPatch,
170-
setting: str | None,
171-
expect_value: bool | None,
172-
):
155+
def test_no_color_env_var(runner, monkeypatch, setting, expect_value, boxed_context):
173156
if setting is None:
174157
monkeypatch.delenv("NO_COLOR", raising=False)
175158
else:
176159
monkeypatch.setenv("NO_COLOR", setting)
177160

178-
_, ctx = invoke_and_get_ctx(
179-
runner, cli_main, ["--schemafile", "schema.json", "foo.json"]
180-
)
181-
assert ctx.color == expect_value
161+
runner.invoke(cli_main, ["--schemafile", "schema.json", "foo.json"])
162+
assert boxed_context.ref.color == expect_value
182163

183164

184165
@pytest.mark.parametrize(
185166
"setting,expected_value",
186167
[(None, None), ("auto", None), ("always", True), ("never", False)],
187168
)
188-
def test_color_cli_option(
189-
runner: CliRunner,
190-
setting: str | None,
191-
expected_value: bool | None,
192-
):
169+
def test_color_cli_option(runner, setting, expected_value, boxed_context):
193170
args = ["--schemafile", "schema.json", "foo.json"]
194171
if setting:
195172
args.extend(("--color", setting))
196-
_, ctx = invoke_and_get_ctx(runner, cli_main, args)
197-
assert ctx.color == expected_value
173+
runner.invoke(cli_main, args)
174+
assert boxed_context.ref.color == expected_value
198175

199176

200177
def test_no_color_env_var_overrides_cli_option(
201-
runner: CliRunner, monkeypatch: pytest.MonkeyPatch
178+
runner, monkeypatch, mock_cli_exec, boxed_context
202179
):
203180
monkeypatch.setenv("NO_COLOR", "1")
204-
205-
_, ctx = invoke_and_get_ctx(
206-
runner, cli_main, ["--color=always", "--schemafile", "schema.json", "foo.json"]
181+
runner.invoke(
182+
cli_main, ["--color=always", "--schemafile", "schema.json", "foo.json"]
207183
)
208-
assert ctx.color is False
184+
assert boxed_context.ref.color is False
209185

210186

211187
@pytest.mark.parametrize(
212188
"setting,expected_value",
213189
[("auto", 0), ("always", 0), ("never", 0), ("anything_else", 2)],
214190
)
215-
def test_color_cli_option_is_choice(
216-
runner: CliRunner, setting: str, expected_value: int
217-
):
191+
def test_color_cli_option_is_choice(runner, setting, expected_value):
218192
assert (
219193
runner.invoke(
220194
cli_main, ["--color", setting, "--schemafile", "schema.json", "foo.json"]

0 commit comments

Comments
 (0)