Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CrystalLintBear.py: Add ameba #2991

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bear-languages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ ClangFunctionDifferenceBear:
- OpenMP
CoffeeLintBear:
- CoffeeScript
CrystalLintBear:
- Crystal
DartLintBear:
- Dart
DennisBear:
Expand Down
18 changes: 18 additions & 0 deletions bear-metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,24 @@ bear_metadata:
- coffeelint
- exe
- npm
CrystalLintBear:
name: CrystalLintBear
subdir: crystal
filename: CrystalLintBear.py
requirements:
exe:
ameba:
distro:
ameba:
packages:
brew: ameba
languages:
- Crystal
tags:
- ameba
- brew
- crystal
- exe
DartLintBear:
name: DartLintBear
subdir: dart
Expand Down
3 changes: 3 additions & 0 deletions bear-requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ r_script_requirements:
lintr:
version: '>=1.0.2'
distro_requirements:
ameba:
packages:
brew: ameba
astyle:
packages:
apt_get: astyle
Expand Down
29 changes: 29 additions & 0 deletions bears/crystal/CrystalLintBear.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from coalib.bearlib.abstractions.Linter import linter
from dependency_management.requirements.DistributionRequirement import (
DistributionRequirement)


@linter(executable='ameba',
output_format='regex',
strip_ansi=True,
output_regex=r'.+:(?P<line>\d+):(?P<column>\d+)\n'
r'.+(?P<origin>[A-Za-z]+): (?P<message>.*)')
class CrystalLintBear:
"""
Checks the code with ``ameba``.

It enforces a consistent Crystal code style
<https://crystal-lang.org/docs/conventions/coding_style.html>, also catches
code smells and wrong code constructions.
"""
LANGUAGE = {'Crystal'}
REQUIREMENTS = {DistributionRequirement(brew='ameba')}
AUTHORS = {'The coala developers'}
AUTHORS_EMAILS = {'coala-devel@googlegroups.com'}
LICENSE = 'AGPL-3.0'
CAN_DETECT = {'Syntax', 'Unused Code', 'Formatting'}
SEE_MORE = 'https://github.com/veelenga/ameba'

@staticmethod
def create_arguments(filename, file, config_file):
return filename,
Empty file added bears/crystal/__init__.py
Empty file.
75 changes: 75 additions & 0 deletions tests/crystal/CrystalLintBearTest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import os
from queue import Queue

from coalib.results.Result import Result
from coalib.settings.Section import Section
from coalib.testing.BearTestHelper import generate_skip_decorator
from coalib.testing.LocalBearTestHelper import LocalBearTestHelper

from bears.crystal.CrystalLintBear import CrystalLintBear


def get_testfile_path(name):
return os.path.join(os.path.dirname(__file__),
'ameba_test_files',
name)


def load_testfile(name):
with open(get_testfile_path(name)) as f:
return f.readlines()


@generate_skip_decorator(CrystalLintBear)
class CrystalLintBearTest(LocalBearTestHelper):

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

def test_redundant_begin_blank_line(self):
filename = 'redundant_begin_test.cr'
file_contents = load_testfile(filename)
self.check_results(
self.uut,
file_contents,
[Result.from_values('CrystalLintBear (RedundantBegin)',
message='Redundant `begin` block detected',
file=get_testfile_path(filename),
line=2,
column=3),
Result.from_values('CrystalLintBear (TrailingBlankLines)',
message='Blank lines detected at the end of '
'the file',
file=get_testfile_path(filename),
line=13,
column=1)],
filename=get_testfile_path(filename))

def test_underscore_cased(self):
filename = 'underscore_cased_test.cr'
file_contents = load_testfile(filename)
self.check_results(
self.uut,
file_contents,
[Result.from_values('CrystalLintBear (MethodNames)',
message='Method name should be underscore-'
'cased: first_name, not first_Name',
file=get_testfile_path(filename),
line=1,
column=1)],
filename=get_testfile_path(filename))

def test_syntax(self):
filename = 'syntax_test.cr'
file_contents = load_testfile(filename)
self.check_results(
self.uut,
file_contents,
[Result.from_values('CrystalLintBear (Syntax)',
message="expecting token 'CONST', not "
"'tagDirective'",
file=get_testfile_path(filename),
line=1,
column=8)],
filename=get_testfile_path(filename))
Empty file added tests/crystal/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions tests/crystal/ameba_test_files/redundant_begin_test.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Parser
def parse(score_text)
begin
score_text.scan(SCORE_PATTERN) do |match|
handle_match(match)
end
rescue err : ParseError
# handle error ...
end
end
end

2 changes: 2 additions & 0 deletions tests/crystal/ameba_test_files/syntax_test.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
struct tagDirective
end
2 changes: 2 additions & 0 deletions tests/crystal/ameba_test_files/underscore_cased_test.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def first_Name
end