diff --git a/src/flake8_json_reporter/reporters.py b/src/flake8_json_reporter/reporters.py index 3637cdb..72fa155 100644 --- a/src/flake8_json_reporter/reporters.py +++ b/src/flake8_json_reporter/reporters.py @@ -32,6 +32,7 @@ def start(self): def stop(self): """Override the default to finish printing JSON.""" self.write_line("}") + super().stop() def beginning(self, filename): """We're starting a new file.""" @@ -83,6 +84,8 @@ def stop(self): if self.files_reported_count > 0: self.write_line("\n") self.write_line("}\n") + # DefaultJSON.stop would write and extra close brace + base.BaseFormatter.stop(self) def beginning(self, filename): """We're starting a new file.""" @@ -139,6 +142,7 @@ def start(self): def stop(self): """Override the default to finish printing JSON.""" self.write_line("}") + super().stop() def beginning(self, filename): """We're starting a new file.""" diff --git a/tests/flake8_json_reporter_test.py b/tests/flake8_json_reporter_test.py index 0e860b1..3888309 100644 --- a/tests/flake8_json_reporter_test.py +++ b/tests/flake8_json_reporter_test.py @@ -1,8 +1,10 @@ +import json from argparse import Namespace import pytest from flake8.violation import Violation +from flake8_json_reporter.reporters import DefaultJSON from flake8_json_reporter.reporters import FormattedJSON @@ -14,6 +16,26 @@ def formatter(): return formatter +@pytest.fixture +def default_formatter_output_file(tmp_path): + """Return a ``DefaultJSON`` instance that captures output to a file""" + options = Namespace( + output_file=tmp_path / "output.json", color=False, tee=False + ) + formatter = DefaultJSON(options) + return formatter + + +@pytest.fixture +def pretty_formatter_output_file(tmp_path): + """Return a ``DefaultJSON`` instance that captures output to a file""" + options = Namespace( + output_file=tmp_path / "output.json", color=False, tee=False + ) + formatter = FormattedJSON(options) + return formatter + + @pytest.fixture def violation(): return Violation( @@ -119,3 +141,61 @@ def test_single_file_multiple_violations(capsys, formatter, violation): } """ assert stdout == expected + + +def test_pretty_single_file_single_file_capture( + pretty_formatter_output_file, violation +): + run(pretty_formatter_output_file, {"main.py": [violation]}) + expected = """\ +{ + "main.py": [ + { + "code": "E222", + "filename": "main.py", + "line_number": 42, + "column_number": 4, + "text": "multiple spaces after operator", + "physical_line": "x = 1" + } + ] +} +""" + actual = pretty_formatter_output_file.filename.read_text() + assert actual == expected + + +def test_default_no_files_file_capture(default_formatter_output_file): + run(default_formatter_output_file, {}) + expected = {} + actual = json.loads(default_formatter_output_file.filename.read_text()) + assert actual == expected + + +def test_default_single_file_no_violations_file_capture( + default_formatter_output_file, +): + run(default_formatter_output_file, {"main.py": []}) + expected = {"main.py": []} + actual = json.loads(default_formatter_output_file.filename.read_text()) + assert actual == expected + + +def test_default_single_file_violations_file_capture( + default_formatter_output_file, violation +): + run(default_formatter_output_file, {"main.py": [violation]}) + expected = { + "main.py": [ + { + "code": "E222", + "filename": "main.py", + "line_number": 42, + "column_number": 4, + "text": "multiple spaces after operator", + "physical_line": "x = 1", + } + ] + } + actual = json.loads(default_formatter_output_file.filename.read_text()) + assert actual == expected