New rule: percent arrays

This commit is contained in:
Vitalii Elenhaupt 2017-11-17 23:41:30 +02:00
parent 52411dadc5
commit 791bfdabb8
No known key found for this signature in database
GPG key ID: 7558EF3A4056C706
3 changed files with 140 additions and 0 deletions

View file

@ -46,6 +46,12 @@ NegatedConditionsInUnless:
# Disallows negated conditions in unless. # Disallows negated conditions in unless.
Enabled: true Enabled: true
PercentArrays:
# Disallows unwanted symbols in percent array literals.
Enabled: true
StringArrayUnwantedSymbols: ',"'
SymbolArrayUnwantedSymbols: ',:'
PredicateName: PredicateName:
# Disallows tautological predicate names, meaning those that start with # Disallows tautological predicate names, meaning those that start with
# the prefix `has_` or the prefix `is_`. # the prefix `has_` or the prefix `is_`.

View file

@ -0,0 +1,69 @@
require "../../spec_helper"
module Ameba::Rule
describe PercentArrays do
subject = PercentArrays.new
it "passes if percent arrays are written correctly" do
s = Source.new %q(
%i(one two three)
%w(one two three)
%i(1 2 3)
%w(1 2 3)
%i()
%w()
)
subject.catch(s).should be_valid
end
it "fails if string percent array has commas" do
s = Source.new %( %w(one, two) )
subject.catch(s).should_not be_valid
end
it "fails if string percent array has quotes" do
s = Source.new %( %w("one" "two") )
subject.catch(s).should_not be_valid
end
it "fails if symbols percent array has commas" do
s = Source.new %( %i(one, two) )
subject.catch(s).should_not be_valid
end
it "fails if symbols percent array has a colon" do
s = Source.new %( %i(:one :two) )
subject.catch(s).should_not be_valid
end
it "reports rule, location and message for %i" do
s = Source.new %(
%i(:one)
), "source.cr"
subject.catch(s).should_not be_valid
error = s.errors.first
error.rule.should_not be_nil
error.location.to_s.should eq "source.cr:2:9"
error.message.should eq(
"Symbols `,:` may be unwanted in %i array literals"
)
end
it "reports rule, location and message for %w" do
s = Source.new %(
%w("one")
), "source.cr"
subject.catch(s).should_not be_valid
error = s.errors.first
error.rule.should_not be_nil
error.location.to_s.should eq "source.cr:2:9"
error.message.should eq(
"Symbols `,\"` may be unwanted in %w array literals"
)
end
end
end

View file

@ -0,0 +1,65 @@
module Ameba::Rule
# A rule that disallows some unwanted symbols in percent array literals.
#
# For example, this is usually written by mistake:
#
# ```
# %i(:one, :two)
# %w("one", "two")
# ```
#
# And the expected example is:
#
# ```
# %i(one two)
# %w(one two)
# ```
#
# YAML configuration example:
#
# ```
# PercentArrays:
# Enabled: true
# StringArrayUnwantedSymbols: ',"'
# SymbolArrayUnwantedSymbols: ',:'
# ```
#
struct PercentArrays < Base
prop string_array_unwanted_symbols = ",\""
prop symbol_array_unwanted_symbols = ",:"
def test(source)
error = start_token = nil
Tokenizer.new(source).run do |token|
case token.type
when :STRING_ARRAY_START, :SYMBOL_ARRAY_START
start_token = token.dup
when :STRING
if start_token && error.nil?
error = array_entry_invalid?(token.value, start_token.not_nil!.raw)
end
when :STRING_ARRAY_END, :SYMBOL_ARRAY_END
if error
source.error(self, start_token.try &.location, error.not_nil!)
end
error = start_token = nil
end
end
end
private def array_entry_invalid?(entry, array_type)
case array_type
when .starts_with? "%w"
check_array_entry entry, string_array_unwanted_symbols, "%w"
when .starts_with? "%i"
check_array_entry entry, symbol_array_unwanted_symbols, "%i"
end
end
private def check_array_entry(entry, symbols, literal)
return unless entry =~ /[#{symbols}]/
"Symbols `#{symbols}` may be unwanted in #{literal} array literals"
end
end
end