Skip to content

Commit

Permalink
Add QuotesBear
Browse files Browse the repository at this point in the history
  • Loading branch information
sils committed Nov 15, 2016
1 parent 07aeda0 commit 0ab4d7e
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 0 deletions.
66 changes: 66 additions & 0 deletions bears/general/QuotesBear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from coalib.bears.LocalBear import LocalBear
from bears.general.AnnotationBear import AnnotationBear
from coalib.results.Diff import Diff
from coalib.results.HiddenResult import HiddenResult
from coalib.results.Result import Result


class QuotesBear(LocalBear):

BEAR_DEPS = {AnnotationBear}
AUTHORS = {'The coala developers'}
AUTHORS_EMAILS = {'[email protected]'}
LICENSE = 'AGPL-3.0'
CAN_DETECT = {'Formatting'}

def correct_single_line_str(self, filename, file, sourcerange,
preferred_quotation):
str_contents = file[sourcerange.start.line - 1][
sourcerange.start.column:sourcerange.end.column-1]

if preferred_quotation in str_contents:
return

before = file[sourcerange.start.line - 1][:sourcerange.start.column-1]
after = file[sourcerange.end.line - 1][sourcerange.end.column:]

replacement = (before + preferred_quotation + str_contents +
preferred_quotation + after)

diff = Diff(file)
diff.change_line(sourcerange.start.line,
file[sourcerange.start.line - 1],
replacement)
yield Result(self, 'You do not use the preferred quotation marks.',
diff.affected_code(filename), diffs={filename: diff})

def run(self, filename, file, dependency_results,
preferred_quotation: str='"'):
"""
Checks and corrects your quotation style.
For all single line strings, this bear will correct the quotation to
your preferred quotation style if that kind of quote is not included
within the string.
:param preferred_quotation: Your preferred quotation character, e.g.
``"`` or ``'``.
"""
if not isinstance(dependency_results[AnnotationBear.name][0],
HiddenResult):
return
if isinstance(dependency_results[AnnotationBear.name][0].contents,
str):
self.err(dependency_results[AnnotationBear.name][0].contents)
return

ranges = dependency_results[AnnotationBear.name][0].contents['strings']

for string_range in ranges:
if (file[string_range.start.line-1][string_range.start.column-1] ==
preferred_quotation):
continue

if string_range.start.line == string_range.end.line:
yield from self.correct_single_line_str(
filename, file, string_range, preferred_quotation)
83 changes: 83 additions & 0 deletions tests/general/QuotesBearTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import unittest
from queue import Queue
from textwrap import dedent

from coalib.results.HiddenResult import HiddenResult
from bears.general.QuotesBear import QuotesBear
from coalib.results.SourceRange import SourceRange
from coalib.settings.Section import Section
from coalib.testing.LocalBearTestHelper import verify_local_bear, execute_bear


class QuotesBearDiffTest(unittest.TestCase):

def setUp(self):
self.section = Section('')
self.uut = QuotesBear(self.section, Queue())

self.double_quote_file = dedent("""
"a string with double quotes!"
'A single quoted string with " in it'
""").splitlines(True)

self.single_quote_file = dedent("""
'a string with single quotes!'
"A double quoted string with ' in it"
""").splitlines(True)

self.filename = 'f'

self.dep_results = {
'AnnotationBear':
[HiddenResult(
'AnnotationBear',
{'comments': (), 'strings': (
SourceRange.from_values(self.filename, 2, 1, 2, 30),
SourceRange.from_values(self.filename, 3, 1, 3, 37))
}
)]
}

def test_valid_quotes(self):
with execute_bear(self.uut, self.filename, self.double_quote_file,
dependency_results=self.dep_results) as results:
self.assertEqual(len(results), 0)

self.section['preferred_quotation'] = "'"
with execute_bear(self.uut, self.filename, self.single_quote_file,
dependency_results=self.dep_results) as results:
self.assertEqual(len(results), 0)

def test_invalid_quotes(self):
with execute_bear(self.uut, self.filename, self.single_quote_file,
dependency_results=self.dep_results) as results:
res_list = list(results)
self.assertEqual(len(res_list), 1)
self.assertEqual(res_list[0].diffs[self.filename].unified_diff,
'--- \n'
'+++ \n'
'@@ -1,3 +1,3 @@\n'
' \n'
"-'a string with single quotes!'\n"
'+"a string with single quotes!"\n'
' "A double quoted string with \' in it"\n')

self.section['preferred_quotation'] = "'"
with execute_bear(self.uut, self.filename, self.double_quote_file,
dependency_results=self.dep_results) as results:
res_list = list(results)
self.assertEqual(len(res_list), 1)
self.assertEqual(res_list[0].diffs[self.filename].unified_diff,
'--- \n'
'+++ \n'
'@@ -1,3 +1,3 @@\n'
' \n'
'-"a string with double quotes!"\n'
"+'a string with double quotes!'\n"
" 'A single quoted string with \" in it'\n")

def test_invalid_dependency_results(self):
dep_results = {'AnnotationBear': [HiddenResult('a', 'error!')]}
with execute_bear(self.uut, self.filename, self.single_quote_file,
dependency_results=dep_results) as results:
self.assertEqual(len(results), 0)

0 comments on commit 0ab4d7e

Please sign in to comment.