Skip to content

Commit

Permalink
FilenameBear.py: Enable default naming convention
Browse files Browse the repository at this point in the history
Add default naming conventions that are widely accepted for
languages like java, javascript and python. Add 'auto' option
to predict the file naming convention.

Closes coala#1083
  • Loading branch information
yash-nisar committed Mar 26, 2017
1 parent 63d31e1 commit 20d4c82
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 9 deletions.
27 changes: 26 additions & 1 deletion bears/general/FilenameBear.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,22 @@ class FilenameBear(LocalBear):
'snake': to_snakecase,
'space': to_spacecase}

_language_naming_convention = {
'.java': 'pascal',
'.js': 'kebab',
'.py': 'snake',
}

def run(self, filename, file,
file_naming_convention: str='snake',
file_naming_convention: str=None,
ignore_uppercase_filenames: bool=True):
"""
Checks whether the filename follows a certain naming-convention.
:param file_naming_convention:
The naming-convention. Supported values are:
- ``auto`` to guess the correct convention. Defaults to ``snake``
if the correct convention cannot be guessed.
- ``camel`` (``thisIsCamelCase``)
- ``kebab`` (``this-is-kebab-case``)
- ``pascal`` (``ThisIsPascalCase``)
Expand All @@ -38,6 +46,23 @@ def run(self, filename, file,
"""
head, tail = os.path.split(filename)
filename_without_extension, extension = os.path.splitext(tail)

if file_naming_convention is None:
self.warn('Please specify a file naming convention explicitly'
' or use "auto".')
file_naming_convention = 'auto'
else:
file_naming_convention = file_naming_convention.lower()

if file_naming_convention == 'auto':
if extension in self._language_naming_convention:
file_naming_convention = self._language_naming_convention[
extension]
else:
self.warn('The file naming convention could not be guessed. '
'Using the default "snake" naming convention.')
file_naming_convention = 'snake'

try:
new_name = self._naming_convention[file_naming_convention](
filename_without_extension)
Expand Down
66 changes: 58 additions & 8 deletions tests/general/FilenameBearTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,13 @@ def test_invalid_naming_convention(self):

log = self.uut.message_queue.get(timeout=1)
self.assertEqual(log.message,
'Invalid file-naming-convention provided: INVALID')
'Invalid file-naming-convention provided: invalid')
self.assertEqual(log.log_level, LOG_LEVEL.ERROR)

def test_snake_case(self):
self.section['file_naming_convention'] = 'snake'
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.py')
self.check_validity(self.uut, [''], filename='XYZ/__init__.py')

self.section['file_naming_convention'] = 'snake'
self.check_validity(self.uut, [''], filename='/a/camCase', valid=False)

def test_camel_case(self):
Expand All @@ -46,11 +45,12 @@ def test_kebab_case(self):
self.check_validity(self.uut, [''], filename='/a/kebab-case')

def test_pascal_case(self):
self.section['file_naming_convention'] = 'pascal'
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.py',
valid=False)
self.check_validity(self.uut, [''], filename='XYZ/__Init__.py')
self.check_validity(self.uut, [''], filename='/a/PascalCase')
for convention in ('Pascal', 'pascal', 'PASCAL'):
self.section['file_naming_convention'] = convention
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.py',
valid=False)
self.check_validity(self.uut, [''], filename='XYZ/__Init__.py')
self.check_validity(self.uut, [''], filename='/a/PascalCase')

def test_space_case(self):
self.section['file_naming_convention'] = 'space'
Expand All @@ -63,8 +63,58 @@ def test_space_case(self):
self.check_validity(self.uut, [''], filename='/a/Space Case')

def test_ignore_upper(self):
self.section['file_naming_convention'] = 'auto'
self.check_validity(self.uut, [''], filename='/LICENSE')

self.section['ignore_uppercase_filenames'] = 'nope'

self.check_validity(self.uut, [''], filename='/LICENSE', valid=False)

def test_default_naming_java(self):
self.section['file_naming_convention'] = 'auto'
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.java',
valid=False)
self.check_validity(self.uut, [''], filename='/Home/xyz/x-y.java',
valid=False)
self.check_validity(self.uut, [''], filename='/Home/xyz/x y.java',
valid=False)
self.check_validity(self.uut, [''], filename='/Home/xyz/XY.java')

def test_default_naming_javascript(self):
self.section['file_naming_convention'] = 'auto'
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.js',
valid=False)
self.check_validity(self.uut, [''], filename='/Home/xyz/x y.js',
valid=False)
self.check_validity(self.uut, [''], filename='/Home/xyz/XY.js')
self.check_validity(self.uut, [''], filename='/Home/xyz/x-y.js')

def test_default_file_naming_python(self):
self.section['file_naming_convention'] = 'auto'
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.py')
self.check_validity(self.uut, [''], filename='XYZ/__init__.py')
self.check_validity(self.uut, [''], filename='/a/x y.py', valid=False)

def test_none_file_naming_convention_warning(self):
self.uut.execute('filename', [])

# Automatic bear messages we want to ignore.
self.uut.message_queue.get()

log = self.uut.message_queue.get(timeout=1)
self.assertEqual(log.message,
'Please specify a file naming convention explicitly'
' or use "auto".')
self.check_validity(self.uut, [''], filename='/Home/xyz/x_y.py')

def test_auto_file_naming_convention_warning(self):
self.section['file_naming_convention'] = 'auto'
self.uut.execute('filename.xyz', [])

# Automatic bear messages we want to ignore.
self.uut.message_queue.get()

log = self.uut.message_queue.get(timeout=1)
self.assertEqual(log.message,
'The file naming convention could not be guessed. '
'Using the default "snake" naming convention...')

0 comments on commit 20d4c82

Please sign in to comment.