New rule: variable names

This commit is contained in:
Vitalii Elenhaupt 2017-11-04 23:13:38 +02:00
parent 3d4c44c333
commit 8440747353
No known key found for this signature in database
GPG key ID: 7558EF3A4056C706
3 changed files with 119 additions and 0 deletions

View file

@ -0,0 +1,61 @@
require "../../spec_helper"
module Ameba
subject = Rules::VariableNames.new
private def it_reports_var_name(content, expected)
it "reports method name #{expected}" do
s = Source.new content
Rules::VariableNames.new.catch(s).should_not be_valid
s.errors.first.message.should contain expected
end
end
describe Rules::VariableNames do
it "passes if var names are underscore-cased" do
s = Source.new %(
class Greeting
@@default_greeting = "Hello world"
def initialize(@custom_greeting = nil)
end
def print_greeting
greeting = @custom_greeting || @@default_greeting
puts greeting
end
end
)
subject.catch(s).should be_valid
end
it_reports_var_name %(myBadNamedVar = 1), "my_bad_named_var"
it_reports_var_name %(wrong_Name = 'y'), "wrong_name"
it_reports_var_name %(
class Greeting
def initialize(@badNamed = nil)
end
end
), "bad_named"
it_reports_var_name %(
class Greeting
@@defaultGreeting = "Hello world"
end
), "default_greeting"
it "reports rule, pos and message" do
s = Source.new %(
badName = "Yeah"
)
subject.catch(s).should_not be_valid
error = s.errors.first
error.rule.should_not be_nil
error.pos.should eq 2
error.message.should eq(
"Var name should be underscore-cased: bad_name, not badName"
)
end
end
end

View file

@ -6,13 +6,16 @@ module Ameba::AST
Call, Call,
Case, Case,
ClassDef, ClassDef,
ClassVar,
Def, Def,
EnumDef, EnumDef,
If, If,
InstanceVar,
LibDef, LibDef,
ModuleDef, ModuleDef,
StringInterpolation, StringInterpolation,
Unless, Unless,
Var,
] ]
abstract class Visitor < Crystal::Visitor abstract class Visitor < Crystal::Visitor

View file

@ -0,0 +1,55 @@
module Ameba::Rules
# A rule that enforces variable names to be in underscored case.
#
# For example, these variable names are considered valid:
#
# ```
# class Greeting
# @@default_greeting = "Hello world"
#
# def initialize(@custom_greeting = nil)
# end
#
# def print_greeting
# greeting = @custom_greeting || @@default_greeting
# puts greeting
# end
# end
# ```
#
# And these are invalid method names:
#
# ```
# myBadNamedVar = 1
# wrong_Name = 2
# ```
#
struct VariableNames < Rule
def test(source)
[
AST::VarVisitor,
AST::InstanceVarVisitor,
AST::ClassVarVisitor,
].each &.new(self, source)
end
private def check_node(source, node)
return if (expected = node.name.underscore) == node.name
source.error self, node.location.try &.line_number,
"Var name should be underscore-cased: #{expected}, not #{node.name}"
end
def test(source, node : Crystal::Var)
check_node source, node
end
def test(source, node : Crystal::InstanceVar)
check_node source, node
end
def test(source, node : Crystal::ClassVar)
check_node source, node
end
end
end