def test_quality(self): """Integration test.""" # Patch the output of `checkstyle` _setup_patch(( dedent(""" [WARN] ../new_file.java:1:1: Line contains a tab character. [WARN] ../new_file.java:13: 'if' construct must use '{}'s. """).strip().encode('ascii'), '' )) expected_violations = [ Violation(1, 'Line contains a tab character.'), Violation(13, "'if' construct must use '{}'s."), ] # Parse the report quality = QualityReporter(checkstyle_driver) # Expect that the name is set self.assertEqual(quality.name(), 'checkstyle') # Measured_lines is undefined for a # quality reporter since all lines are measured self.assertEqual(quality.measured_lines('../new_file.java'), None) # Expect that we get violations for file1.java only # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations('../new_file.java') self.assertEqual(len(actual_violations), len(expected_violations)) for expected in expected_violations: self.assertIn(expected, actual_violations)
def test_no_python_file(self): quality = QualityReporter(PylintDriver()) file_paths = ['file1.coffee', 'subdir/file2.js'] # Expect that we get no results because no Python files for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_no_java_file(self): quality = QualityReporter(CheckstyleXmlDriver()) file_paths = ["file1.coffee", "subdir/file2.js"] # Expect that we get no results because no Java files for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_quality(self, process_patcher): """Integration test.""" # Patch the output of `checkstyle` process_patcher(( dedent(""" [WARN] ../new_file.java:1:1: Line contains a tab character. [WARN] ../new_file.java:13: 'if' construct must use '{}'s. """).strip().encode("ascii"), "", )) expected_violations = [ Violation(1, "Line contains a tab character."), Violation(13, "'if' construct must use '{}'s."), ] # Parse the report quality = QualityReporter(checkstyle_driver) # Expect that the name is set assert quality.name() == "checkstyle" # Measured_lines is undefined for a # quality reporter since all lines are measured assert not quality.measured_lines("../new_file.java") # Expect that we get violations for file1.java only # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations("../new_file.java") assert len(actual_violations) == len(expected_violations) for expected in expected_violations: assert expected in actual_violations
def test_no_java_file(self): quality = QualityReporter(FindbugsXmlDriver()) file_paths = ["file1.coffee", "subdir/file2.js"] # Expect that we get no results because no Java files for path in file_paths: result = quality.violations(path) assert result == []
def test_quality_error(self, mocker, process_patcher): # Patch the output stderr/stdout and returncode of `checkstyle` process_patcher( ( dedent(""" <?xml version="1.0" encoding="UTF-8"?> <checkstyle version="8.0"> <file name="file1.java"> <error line="1" severity="error" message="Missing docstring"/> </file> </checkstyle> """), b"oops", ), status_code=1, ) # Parse the report code = mocker.patch( "diff_cover.violationsreporters.java_violations_reporter.run_command_for_code" ) code.return_value = 0 quality = QualityReporter(CheckstyleXmlDriver()) with pytest.raises(CommandError): quality.violations("file1.java")
def test_quality_error(self): # Patch the output stderr/stdout and returncode of `checkstyle` _setup_patch( ( dedent(""" <?xml version="1.0" encoding="UTF-8"?> <checkstyle version="8.0"> <file name="file1.java"> <error line="1" severity="error" message="Missing docstring"/> </file> </checkstyle> """), b"oops", ), status_code=1, ) # Parse the report with patch( "diff_cover.violationsreporters.java_violations_reporter.run_command_for_code" ) as code: code.return_value = 0 quality = QualityReporter(CheckstyleXmlDriver()) # Expect an error self.assertRaises(CommandError, quality.violations, "file1.java")
def test_file_does_not_exist(self): quality = QualityReporter(flake8_driver) file_paths = ['ajshdjlasdhajksdh.py'] # Expect that we get no results because that file does not exist for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_quality(self): """Integration test.""" # Patch the output of `pydocstye` _setup_patch((dedent(""" ../new_file.py:1 at module level: D100: Missing docstring in public module ../new_file.py:13 in public function `gather`: D103: Missing docstring in public function """).strip().encode('ascii'), '')) expected_violations = [ Violation(1, 'D100: Missing docstring in public module'), Violation(13, "D103: Missing docstring in public function"), ] # Parse the report quality = QualityReporter(pydocstyle_driver) # Expect that the name is set self.assertEqual(quality.name(), 'pydocstyle') # Measured_lines is undefined for a # quality reporter since all lines are measured self.assertEqual(quality.measured_lines('../new_file.py'), None) # Expect that we get violations for file1.py only # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations('../new_file.py') self.assertEqual(len(actual_violations), len(expected_violations)) for expected in expected_violations: self.assertIn(expected, actual_violations)
def test_no_quality_issues_emptystring(self): # Patch the output of `pyflakes` _setup_patch((b'', b'')) # Parse the report quality = QualityReporter(pyflakes_driver) self.assertEqual([], quality.violations('file1.py'))
def test_no_js_file(self): quality = QualityReporter(self._get_out()) file_paths = ['file1.py', 'subdir/file2.java'] # Expect that we get no results because no JS files for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_quality(self): # Patch the output of `pyflakes` return_string = '\n' + dedent(""" ../new_file.py:328: undefined name '_thing' ../new_file.py:418: 'random' imported but unused """).strip() + '\n' _setup_patch((return_string.encode('utf-8'), b'')) # Parse the report quality = QualityReporter(pyflakes_driver) # Expect that the name is set self.assertEqual(quality.name(), 'pyflakes') # Measured_lines is undefined for # a quality reporter since all lines are measured self.assertEqual(quality.measured_lines('../new_file.py'), None) # Expect that we get the right violations expected_violations = [ Violation(328, "undefined name '_thing'"), Violation(418, "'random' imported but unused") ] self.assertEqual(expected_violations, quality.violations('../new_file.py'))
def test_quality(self): # Patch the output of `pep8` _mock_communicate = patch.object(Popen, 'communicate').start() return_string = '\n' + dedent(""" ../new_file.py:1:17: E231 whitespace ../new_file.py:3:13: E225 whitespace ../new_file.py:7:1: E302 blank lines """).strip() + '\n' _setup_patch((return_string.encode('utf-8'), b'')) # Parse the report quality = QualityReporter(pep8_driver) # Expect that the name is set self.assertEqual(quality.name(), 'pep8') # Measured_lines is undefined for # a quality reporter since all lines are measured self.assertEqual(quality.measured_lines('../new_file.py'), None) # Expect that we get the right violations expected_violations = [ Violation(1, 'E231 whitespace'), Violation(3, 'E225 whitespace'), Violation(7, 'E302 blank lines') ] self.assertEqual(expected_violations, quality.violations('../new_file.py'))
def test_no_quality_issues_newline(self): _setup_patch((b'\n', b''), 0) # Parse the report quality = QualityReporter(PylintDriver()) self.assertEqual([], quality.violations('file1.py'))
def test_no_python_file(self): """Expect that we get no results because no Python files.""" quality = QualityReporter(pydocstyle_driver) file_paths = ['file1.coffee', 'subdir/file2.js'] for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_quality(self): """ Test basic scenarios, including special characters that would appear in JavaScript and mixed quotation marks """ # Patch the output of the linter cmd return_string = '\n' + dedent(""" ../test_file.js: line 3, col 9, Missing "use strict" statement. ../test_file.js: line 10, col 17, '$hi' is defined but never used. """).strip() + '\n' self.subproc_mock.communicate.return_value = (( return_string.encode('utf-8'), b'')) self._mock_communicate.return_value = self.subproc_mock # Parse the report quality = QualityReporter(self._get_out()) # Expect that the name is set self.assertEqual(quality.name(), self.quality_name) # Measured_lines is undefined for # a quality reporter since all lines are measured self.assertEqual(quality.measured_lines('../blah.js'), None) # Expect that we get the right violations expected_violations = [ Violation(3, 'Missing "use strict" statement.'), Violation(10, "'$hi' is defined but never used."), ] self.assertEqual(expected_violations, quality.violations('../test_file.js'))
def test_no_java_file(self): quality = QualityReporter(FindbugsXmlDriver()) file_paths = ['file1.coffee', 'subdir/file2.js'] # Expect that we get no results because no Java files for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_no_java_file(self): """Expect that we get no results because no Python files.""" quality = QualityReporter(checkstyle_driver) file_paths = ["file1.coffee", "subdir/file2.js"] for path in file_paths: result = quality.violations(path) self.assertEqual(result, [])
def test_quality(self): # Patch the output of `checkstyle` _setup_patch( ( dedent( """ <?xml version="1.0" encoding="UTF-8"?> <checkstyle version="8.0"> <file name="file1.java"> <error line="1" severity="error" message="Missing docstring"/> <error line="2" severity="error" message="Unused variable 'd'"/> <error line="2" severity="warning" message="TODO: Not the real way we'll store usages!"/> <error line="579" severity="error" message="Unable to import 'rooted_paths'"/> <error line="113" severity="error" message="Unused argument 'cls'"/> <error line="150" severity="error" message="error while code parsing ([Errno 2] No such file or directory)"/> <error line="149" severity="error" message="Comma not followed by a space"/> </file> <file name="path/to/file2.java"> <error line="100" severity="error" message="Access to a protected member"/> </file> </checkstyle> """ ) .strip() .encode("ascii"), "", ) ) expected_violations = [ Violation(1, "error: Missing docstring"), Violation(2, "error: Unused variable 'd'"), Violation(2, "warning: TODO: Not the real way we'll store usages!"), Violation(579, "error: Unable to import 'rooted_paths'"), Violation( 150, "error: error while code parsing ([Errno 2] No such file or directory)", ), Violation(149, "error: Comma not followed by a space"), Violation(113, "error: Unused argument 'cls'"), ] # Parse the report quality = QualityReporter(CheckstyleXmlDriver()) # Expect that the name is set self.assertEqual(quality.name(), "checkstyle") # Measured_lines is undefined for a # quality reporter since all lines are measured self.assertIsNone(quality.measured_lines("file1.java")) # Expect that we get violations for file1.java only # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations("file1.java") self.assertEqual(len(actual_violations), len(expected_violations)) for expected in expected_violations: self.assertIn(expected, actual_violations)
def test_no_quality_issues_newline(self): # Patch the output of `pep8` _setup_patch((b'\n', b'')) # Parse the report quality = QualityReporter(pep8_driver) self.assertEqual([], quality.violations('file1.py'))
def test_unicode_continuation_char(self): _setup_patch((b"file.py:2: [W1401]" b" Invalid char '\xc3'", ''), 0) # Since we are replacing characters we can't interpet, this should # return a valid string with the char replaced with '?' quality = QualityReporter(PylintDriver()) violations = quality.violations(u'file.py') self.assertEqual(violations, [Violation(2, u"W1401: Invalid char '\ufffd'")])
def test_no_quality_issues_emptystring(self): # Patch the output of `pylint` _mock_communicate = patch.object(Popen, 'communicate').start() _mock_communicate.return_value = (b'', b'') # Parse the report quality = QualityReporter(PylintDriver()) self.assertEqual([], quality.violations('file1.py'))
def test_quality_reporter(self, mock_stderr): with patch('diff_cover.violationsreporters.base.run_command_for_code' ) as code: code.return_value = 0 reporter = QualityReporter(pep8_driver) with self.assertRaises(OSError): reporter.violations("path/to/file.py") self.assertEqual(mock_stderr.getvalue(), "pep8 path/to/file.py")
def test_quality_pregenerated_report(self): # When the user provides us with a pre-generated checkstyle report # then use that instead of calling checkstyle directly. checkstyle_reports = [ BytesIO( dedent(""" <?xml version="1.0" encoding="UTF-8"?> <checkstyle version="8.0"> <file name="path/to/file.java"> <error line="1" severity="error" message="Missing docstring"/> <error line="57" severity="warning" message="TODO the name of this method is a little bit confusing"/> </file> <file name="another/file.java"> <error line="41" severity="error" message="Specify string format arguments as logging function parameters"/> <error line="175" severity="error" message="Operator not preceded by a space"/> <error line="259" severity="error" message="Invalid name '' for type variable (should match [a-z_][a-z0-9_]{2,30}$)"/> </file> </checkstyle> """).strip().encode("utf-8")), BytesIO( dedent(""" <?xml version="1.0" encoding="UTF-8"?> <checkstyle version="8.0"> <file name="path/to/file.java"> <error line="183" severity="error" message="Invalid name '' for type argument (should match [a-z_][a-z0-9_]{2,30}$)"/> </file> <file name="another/file.java"> <error line="183" severity="error" message="Missing docstring"/> </file> </checkstyle> """).strip().encode("utf-8")), ] # Generate the violation report quality = QualityReporter(CheckstyleXmlDriver(), reports=checkstyle_reports) # Expect that we get the right violations expected_violations = [ Violation(1, "error: Missing docstring"), Violation( 57, "warning: TODO the name of this method is a little bit confusing" ), Violation( 183, "error: Invalid name '' for type argument (should match [a-z_][a-z0-9_]{2,30}$)", ), ] # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations("path/to/file.java") self.assertEqual(len(actual_violations), len(expected_violations)) for expected in expected_violations: self.assertIn(expected, actual_violations)
def test_no_quality_issues_emptystring(self): # Patch the output of the linter cmd self.subproc_mock.communicate.return_value = (b'', b'') self._mock_communicate.return_value = self.subproc_mock # Parse the report quality = QualityReporter(self._get_out()) self.assertEqual([], quality.violations('file1.js'))
def test_no_quality_issues_newline(self): # Patch the output of `flake8` _mock_communicate = patch.object(Popen, 'communicate').start() _mock_communicate.return_value = (b'\n', b'') # Parse the report quality = QualityReporter(flake8_driver) self.assertEqual([], quality.violations('file1.py'))
def test_non_integer_line_num(self): _setup_patch((dedent(u""" file.py:not_a_number: C0111: Missing docstring file.py:\u8911: C0111: Missing docstring """).encode('utf-8'), ''), 0) # None of the violations have a valid line number, so they should all be skipped violations = QualityReporter(PylintDriver()).violations(u'file.py') self.assertEqual(violations, [])
def test_non_integer_line_num(self): _mock_communicate = patch.object(Popen, 'communicate').start() _mock_communicate.return_value = (dedent(u""" file.py:not_a_number: C0111: Missing docstring file.py:\u8911: C0111: Missing docstring """).encode('utf-8'), '') # None of the violations have a valid line number, so they should all be skipped violations = QualityReporter(PylintDriver()).violations(u'file.py') self.assertEqual(violations, [])
def test_quality(self): # Patch the output of `pylint` _setup_patch((dedent(""" file1.py:1: [C0111] Missing docstring file1.py:1: [C0111, func_1] Missing docstring file1.py:2: [W0612, cls_name.func] Unused variable 'd' file1.py:2: [W0511] TODO: Not the real way we'll store usages! file1.py:579: [F0401] Unable to import 'rooted_paths' file1.py:113: [W0613, cache_relation.clear_pk] Unused argument 'cls' file1.py:150: [F0010] error while code parsing ([Errno 2] No such file or directory) file1.py:149: [C0324, Foo.__dict__] Comma not followed by a space self.peer_grading._find_corresponding_module_for_location(Location('i4x','a','b','c','d')) file1.py:162: [R0801] Similar lines in 2 files ==file1:162 ==student.views:4 import json import logging import random path/to/file2.py:100: [W0212, openid_login_complete] Access to a protected member """).strip().encode('ascii'), '')) expected_violations = [ Violation(1, 'C0111: Missing docstring'), Violation(1, 'C0111: func_1: Missing docstring'), Violation(2, "W0612: cls_name.func: Unused variable 'd'"), Violation(2, "W0511: TODO: Not the real way we'll store usages!"), Violation(579, "F0401: Unable to import 'rooted_paths'"), Violation( 150, "F0010: error while code parsing ([Errno 2] No such file or directory)" ), Violation(149, "C0324: Foo.__dict__: Comma not followed by a space"), Violation(162, "R0801: Similar lines in 2 files"), Violation(113, "W0613: cache_relation.clear_pk: Unused argument 'cls'") ] # Parse the report quality = QualityReporter(PylintDriver()) # Expect that the name is set self.assertEqual(quality.name(), 'pylint') # Measured_lines is undefined for a # quality reporter since all lines are measured self.assertEqual(quality.measured_lines('file1.py'), None) # Expect that we get violations for file1.py only # We're not guaranteed that the violations are returned # in any particular order. actual_violations = quality.violations('file1.py') self.assertEqual(len(actual_violations), len(expected_violations)) for expected in expected_violations: self.assertIn(expected, actual_violations)
def test_not_installed(self): """ If linter is not available via commandline, it should raise an EnvironmentError """ self._mock_command_simple = patch( 'diff_cover.violationsreporters.violations_reporter.run_command_for_code' ).start() self._mock_command_simple.return_value = 1 with self.assertRaises(EnvironmentError): QualityReporter(self._get_out()).violations('test.js')