Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This bear checks for spellings and grammatical mistakes on the descriptions of documentation comments.
- Loading branch information
1 parent
92b1f28
commit 05f9d01
Showing
6 changed files
with
216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import shutil | ||
|
||
from coalib.bearlib.languages.documentation.DocumentationComment import ( | ||
DocumentationComment) | ||
from coalib.bearlib.languages.documentation.DocstyleDefinition import ( | ||
DocstyleDefinition) | ||
from coalib.bearlib.languages.documentation.DocBaseClass import ( | ||
DocBaseClass) | ||
from dependency_management.requirements.PipRequirement import PipRequirement | ||
from coalib.bears.LocalBear import LocalBear | ||
from coalib.results.Result import Result | ||
from coalib.settings.Setting import typed_list | ||
|
||
|
||
class DocGrammarBear(DocBaseClass, LocalBear): | ||
LANGUAGES = {language for docstyle, language in | ||
DocstyleDefinition.get_available_definitions()} | ||
REQUIREMENTS = {PipRequirement('language-check', '1.0')} | ||
AUTHORS = {'The coala developers'} | ||
AUTHORS_EMAILS = {'coala-devel@googlegroups.com'} | ||
LICENSE = 'AGPL-3.0' | ||
CAN_DETECT = {'Documentation', 'Spelling', 'Grammar'} | ||
CAN_FIX = {'Documentation', 'Spelling', 'Grammar'} | ||
|
||
@classmethod | ||
def check_prerequisites(cls): | ||
if shutil.which('java') is None: | ||
return 'java is not installed.' | ||
else: | ||
try: | ||
from language_check import LanguageTool, correct | ||
LanguageTool | ||
correct | ||
return True | ||
except ImportError: # pragma: no cover | ||
return 'Please install the `language-check` pip package.' | ||
|
||
def process_documentation(self, | ||
parsed, | ||
natural_language, | ||
languagetool_disable_rules): | ||
""" | ||
This fixes the parsed documentation comment. | ||
:param parsed: | ||
Contains parsed documentation comment. | ||
:param natural_language: | ||
A locale representing the language you want to have checked. | ||
Default is set to 'en-US'. | ||
:param languagetool_disable_rules: | ||
List of rules to disable checks for. | ||
:return: | ||
A tuple of fixed parsed documentation comment and warning_desc. | ||
""" | ||
# Defer import so the check_prerequisites can be run without | ||
# language_check being there. | ||
from language_check import LanguageTool, correct | ||
|
||
tool = LanguageTool(natural_language) | ||
tool.disabled.update(languagetool_disable_rules) | ||
|
||
metadata = iter(parsed) | ||
|
||
new_metadata = [] | ||
for comment in metadata: | ||
matches = tool.check(comment.desc) | ||
new_desc = correct(comment.desc, matches) | ||
new_metadata.append(comment._replace(desc=new_desc)) | ||
|
||
return (new_metadata, | ||
'Documentation has invalid Grammar/Spelling') | ||
|
||
def run(self, filename, file, language: str, | ||
docstyle: str='default', natural_language: str='en-US', | ||
languagetool_disable_rules: typed_list(str)=()): | ||
""" | ||
Checks the main description and comments description of documentation | ||
with LanguageTool. | ||
:param language: | ||
The programming language of the file(s). | ||
:param docstyle: | ||
The docstyle to use. For example ``default`` or ``doxygen``. | ||
Docstyles are language dependent, meaning not every language is | ||
supported by a certain docstyle. | ||
:param natural_language: | ||
A locale representing the language you want to have checked. | ||
Default is set to 'en-US'. | ||
:param languagetool_disable_rules: | ||
List of rules to disable checks for. | ||
""" | ||
for doc_comment in self.extract(file, language, docstyle): | ||
parsed = doc_comment.parse() | ||
|
||
(new_metadata, warning_desc) = self.process_documentation( | ||
parsed, natural_language, languagetool_disable_rules) | ||
|
||
new_comment = DocumentationComment.from_metadata( | ||
new_metadata, doc_comment.docstyle_definition, | ||
doc_comment.marker, doc_comment.indent, doc_comment.position) | ||
|
||
if new_comment != doc_comment: | ||
# Something changed, let's apply a result. | ||
diff = self.generate_diff(file, doc_comment, new_comment) | ||
|
||
yield Result( | ||
origin=self, | ||
message=warning_desc, | ||
affected_code=(diff.range(filename),), | ||
diffs={filename: diff}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
from queue import Queue | ||
import os.path | ||
import unittest | ||
import shutil | ||
|
||
from coalib.results.Diff import Diff | ||
from coalib.settings.Section import Section | ||
from coalib.testing.LocalBearTestHelper import execute_bear | ||
|
||
from bears.documentation.DocGrammarBear import DocGrammarBear | ||
|
||
try: | ||
import language_check | ||
language_check | ||
except ImportError as err: | ||
raise unittest.case.SkipTest(str(err)) | ||
|
||
|
||
def load_testfile(filename): | ||
filepath = os.path.join(os.path.dirname(__file__), 'test_files', | ||
'DocGrammarBear', filename) | ||
with open(filepath) as fl: | ||
return fl.read() | ||
|
||
|
||
def test(test_file, expected_file, optional_setting=None): | ||
def test_function(self): | ||
test_file_content = load_testfile(test_file).splitlines(True) | ||
|
||
arguments = {'language': 'python', 'docstyle': 'default'} | ||
if optional_setting: | ||
arguments.update(optional_setting) | ||
section = Section('test-section') | ||
for key, value in arguments.items(): | ||
section[key] = value | ||
|
||
with execute_bear( | ||
DocGrammarBear(section, Queue()), | ||
test_file, | ||
test_file_content, | ||
**arguments) as results: | ||
|
||
diff = Diff(test_file_content) | ||
for result in results: | ||
# Only the given test file should contain a patch. | ||
self.assertEqual(len(result.diffs), 1) | ||
|
||
diff += result.diffs[test_file] | ||
|
||
correct_file_content = load_testfile(expected_file).splitlines(True) | ||
|
||
self.assertEqual(correct_file_content, diff.modified) | ||
|
||
return test_function | ||
|
||
|
||
class DocGrammarBearTest(unittest.TestCase): | ||
|
||
def test_check_prerequisites(self): | ||
_shutil_which = shutil.which | ||
try: | ||
shutil.which = lambda *args, **kwargs: None | ||
self.assertEqual(DocGrammarBear.check_prerequisites(), | ||
'java is not installed.') | ||
|
||
shutil.which = lambda *args, **kwargs: 'path/to/java' | ||
self.assertTrue(DocGrammarBear.check_prerequisites()) | ||
finally: | ||
shutil.which = _shutil_which | ||
|
||
test_bad1 = test('bad_file.py.test', 'bad_file.py.test.correct') | ||
test_good1 = test('good_file.py.test', 'good_file.py.test') | ||
test_good2 = test( | ||
'good_file2.py.test', 'good_file2.py.test', | ||
{'languagetool_disable_rules': 'UPPERCASE_SENTENCE_START'}) |
8 changes: 8 additions & 0 deletions
8
tests/documentation/test_files/DocGrammarBear/bad_file.py.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
def improper_grammar(param1): | ||
""" | ||
Documntation contains gramatical mistakess.DocGrammarBear doesnt check | ||
for style. | ||
:param param1: Contains parameter descrption. | ||
:return: returns nothing. first letter small. | ||
""" | ||
return None |
8 changes: 8 additions & 0 deletions
8
tests/documentation/test_files/DocGrammarBear/bad_file.py.test.correct
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
def improper_grammar(param1): | ||
""" | ||
Documentation contains grammatical mistakes. DocGrammarBear doesn't check | ||
for style. | ||
:param param1: Contains parameter description. | ||
:return: Returns nothing. First letter small. | ||
""" | ||
return None |
8 changes: 8 additions & 0 deletions
8
tests/documentation/test_files/DocGrammarBear/good_file.py.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
def docstring_grammar_correct(dummy): | ||
""" | ||
This documentation has the correct grammar. | ||
|
||
:param dummy: Dummy description. | ||
:return: Returns Nothing. | ||
""" | ||
return None |
7 changes: 7 additions & 0 deletions
7
tests/documentation/test_files/DocGrammarBear/good_file2.py.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
def check_disabled_settings(dummy): | ||
""" | ||
This documentation has a setting disabled. sentence starting with lowercase. | ||
|
||
:param dummy: dummy description. | ||
:return: Nothing. | ||
""" return None |