From 765a0b74bc5f2cface4595661f8832a3aebc68ba Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 3 Dec 2021 15:53:14 +0100 Subject: [PATCH] Add endLine and endColumn keys to JSONReporter (#5456) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> Co-authored-by: Pierre Sassoulas --- ChangeLog | 4 ++ doc/whatsnew/2.12.rst | 4 ++ pylint/reporters/json_reporter.py | 2 + tests/unittest_reporters_json.py | 80 ++++++++++++++++++++++++------- tests/unittest_reporting.py | 4 ++ 5 files changed, 76 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2aa47648bc..b3292e170a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,10 @@ Release date: TBA Closes #5437 +* Add ``endLine`` and ``endColumn`` keys to output of ``JSONReporter``. + + Closes #5380 + * Fixed handling of Google-style parameter specifications where descriptions are on the line following the parameter name. These were generating false positives for ``missing-param-doc``. diff --git a/doc/whatsnew/2.12.rst b/doc/whatsnew/2.12.rst index be4559af83..98fda883b0 100644 --- a/doc/whatsnew/2.12.rst +++ b/doc/whatsnew/2.12.rst @@ -246,3 +246,7 @@ Other Changes ``pylint/testutil/`` are still unstable and might be modified in the near future. Closes #4412 #5287 + +* Add ``endLine`` and ``endColumn`` keys to output of ``JSONReporter``. + + Closes #5380 diff --git a/pylint/reporters/json_reporter.py b/pylint/reporters/json_reporter.py index 8c43b0a3ba..9299d581b9 100644 --- a/pylint/reporters/json_reporter.py +++ b/pylint/reporters/json_reporter.py @@ -40,6 +40,8 @@ def display_messages(self, layout: Optional["Section"]) -> None: "obj": msg.obj, "line": msg.line, "column": msg.column, + "endLine": msg.end_line, + "endColumn": msg.end_column, "path": msg.path, "symbol": msg.symbol, "message": msg.msg or "", diff --git a/tests/unittest_reporters_json.py b/tests/unittest_reporters_json.py index ed6ed74a4d..7da5c8bf8c 100644 --- a/tests/unittest_reporters_json.py +++ b/tests/unittest_reporters_json.py @@ -25,29 +25,67 @@ from pylint.reporters.ureports.nodes import EvaluationSection expected_score_message = "Expected score message" -expected_result = [ - [ - ("column", 0), - ("line", 1), - ("message", "Line too long (1/2)"), - ("message-id", "C0301"), - ("module", "0123"), - ("obj", ""), - ("path", "0123"), - ("symbol", "line-too-long"), - ("type", "convention"), - ] -] def test_simple_json_output_no_score() -> None: - report = get_linter_result(score=False) + """Test JSON reporter with no score""" + message = { + "msg": "line-too-long", + "line": 1, + "args": (1, 2), + "end_line": None, + "end_column": None, + } + expected = [ + { + "type": "convention", + "module": "0123", + "obj": "", + "line": 1, + "column": 0, + "endLine": None, + "endColumn": None, + "path": "0123", + "symbol": "line-too-long", + "message": "Line too long (1/2)", + "message-id": "C0301", + } + ] + report = get_linter_result(score=False, message=message) + assert len(report) == 1 + assert json.dumps(report) == json.dumps(expected) + + +def test_simple_json_output_no_score_with_end_line() -> None: + """Test JSON reporter with no score with end_line and end_column""" + message = { + "msg": "line-too-long", + "line": 1, + "args": (1, 2), + "end_line": 1, + "end_column": 4, + } + expected = [ + { + "type": "convention", + "module": "0123", + "obj": "", + "line": 1, + "column": 0, + "endLine": 1, + "endColumn": 4, + "path": "0123", + "symbol": "line-too-long", + "message": "Line too long (1/2)", + "message-id": "C0301", + } + ] + report = get_linter_result(score=False, message=message) assert len(report) == 1 - report_result = [sorted(report[0].items(), key=lambda item: item[0])] - assert report_result == expected_result + assert json.dumps(report) == json.dumps(expected) -def get_linter_result(score: bool) -> List[Dict[str, Any]]: +def get_linter_result(score: bool, message: Dict[str, Any]) -> List[Dict[str, Any]]: output = StringIO() reporter = JSONReporter(output) linter = PyLinter(reporter=reporter) @@ -56,7 +94,13 @@ def get_linter_result(score: bool) -> List[Dict[str, Any]]: linter.config.score = score linter.open() linter.set_current_module("0123") - linter.add_message("line-too-long", line=1, args=(1, 2)) + linter.add_message( + message["msg"], + line=message["line"], + args=message["args"], + end_lineno=message["end_line"], + end_col_offset=message["end_column"], + ) # we call those methods because we didn't actually run the checkers if score: reporter.display_reports(EvaluationSection(expected_score_message)) diff --git a/tests/unittest_reporting.py b/tests/unittest_reporting.py index 3e6fdafd15..8b6fca8096 100644 --- a/tests/unittest_reporting.py +++ b/tests/unittest_reporting.py @@ -219,6 +219,8 @@ def test_multi_format_output(tmp_path): ' "obj": "",\n' ' "line": 1,\n' ' "column": 0,\n' + ' "endLine": null,\n' + ' "endColumn": null,\n' f' "path": {escaped_source_file},\n' ' "symbol": "missing-module-docstring",\n' ' "message": "Missing module docstring",\n' @@ -230,6 +232,8 @@ def test_multi_format_output(tmp_path): ' "obj": "",\n' ' "line": 1,\n' ' "column": 0,\n' + ' "endLine": null,\n' + ' "endColumn": null,\n' f' "path": {escaped_source_file},\n' ' "symbol": "line-too-long",\n' ' "message": "Line too long (1/2)",\n'