-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #419 from crystal-ameba/add-block-parameter-name-rule
Add `Naming/BlockParameterName` rule
- Loading branch information
Showing
11 changed files
with
180 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
require "../../../spec_helper" | ||
|
||
module Ameba::Rule::Naming | ||
subject = BlockParameterName.new | ||
.tap(&.min_name_length = 3) | ||
.tap(&.allowed_names = %w[_ e i j k v]) | ||
|
||
describe BlockParameterName do | ||
it "passes if block parameter name matches #allowed_names" do | ||
subject.allowed_names.each do |name| | ||
expect_no_issues subject, <<-CRYSTAL | ||
%w[].each { |#{name}| } | ||
CRYSTAL | ||
end | ||
end | ||
|
||
it "fails if block parameter name doesn't match #allowed_names" do | ||
expect_issue subject, <<-CRYSTAL | ||
%w[].each { |x| } | ||
# ^ error: Disallowed block parameter name found | ||
CRYSTAL | ||
end | ||
|
||
context "properties" do | ||
context "#min_name_length" do | ||
it "allows setting custom values" do | ||
rule = BlockParameterName.new | ||
rule.allowed_names = %w[a b c] | ||
|
||
rule.min_name_length = 3 | ||
expect_issue rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
# ^ error: Disallowed block parameter name found | ||
CRYSTAL | ||
|
||
rule.min_name_length = 1 | ||
expect_no_issues rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
CRYSTAL | ||
end | ||
end | ||
|
||
context "#allow_names_ending_in_numbers" do | ||
it "allows setting custom values" do | ||
rule = BlockParameterName.new | ||
rule.min_name_length = 1 | ||
rule.allowed_names = %w[] | ||
|
||
rule.allow_names_ending_in_numbers = false | ||
expect_issue rule, <<-CRYSTAL | ||
%w[].each { |x1| } | ||
# ^ error: Disallowed block parameter name found | ||
CRYSTAL | ||
|
||
rule.allow_names_ending_in_numbers = true | ||
expect_no_issues rule, <<-CRYSTAL | ||
%w[].each { |x1| } | ||
CRYSTAL | ||
end | ||
end | ||
|
||
context "#allowed_names" do | ||
it "allows setting custom names" do | ||
rule = BlockParameterName.new | ||
rule.min_name_length = 3 | ||
|
||
rule.allowed_names = %w[a b c] | ||
expect_issue rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
# ^ error: Disallowed block parameter name found | ||
CRYSTAL | ||
|
||
rule.allowed_names = %w[x y z] | ||
expect_no_issues rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
CRYSTAL | ||
end | ||
end | ||
|
||
context "#forbidden_names" do | ||
it "allows setting custom names" do | ||
rule = BlockParameterName.new | ||
rule.min_name_length = 1 | ||
rule.allowed_names = %w[] | ||
|
||
rule.forbidden_names = %w[x y z] | ||
expect_issue rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
# ^ error: Disallowed block parameter name found | ||
CRYSTAL | ||
|
||
rule.forbidden_names = %w[a b c] | ||
expect_no_issues rule, <<-CRYSTAL | ||
%w[].each { |x| } | ||
CRYSTAL | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
module Ameba::Rule::Naming | ||
# A rule that reports non-descriptive block parameter names. | ||
# | ||
# Favour this: | ||
# | ||
# ``` | ||
# tokens.each { |token| token.last_accessed_at = Time.utc } | ||
# ``` | ||
# | ||
# Over this: | ||
# | ||
# ``` | ||
# tokens.each { |t| t.last_accessed_at = Time.utc } | ||
# ``` | ||
# | ||
# YAML configuration example: | ||
# | ||
# ``` | ||
# Naming/BlockParameterName: | ||
# Enabled: true | ||
# MinNameLength: 3 | ||
# AllowNamesEndingInNumbers: true | ||
# AllowedNames: [_, e, i, j, k, v, x, y, ex, io, ws, tx, id, k1, k2, v1, v2] | ||
# ForbiddenNames: [] | ||
# ``` | ||
class BlockParameterName < Base | ||
properties do | ||
description "Disallows non-descriptive block parameter names" | ||
min_name_length 3 | ||
allow_names_ending_in_numbers true | ||
allowed_names %w[_ e i j k v x y ex io ws tx id k1 k2 v1 v2] | ||
forbidden_names %w[] | ||
end | ||
|
||
MSG = "Disallowed block parameter name found" | ||
|
||
def test(source, node : Crystal::Call) | ||
node.try(&.block).try(&.args).try &.each do |arg| | ||
issue_for arg, MSG unless valid_name?(arg.name) | ||
end | ||
end | ||
|
||
private def valid_name?(name) | ||
return true if name.blank? # happens with compound names like `(arg1, arg2)` | ||
return true if name.in?(allowed_names) | ||
|
||
return false if name.in?(forbidden_names) | ||
return false if name.size < min_name_length | ||
return false if name[-1].ascii_number? && !allow_names_ending_in_numbers? | ||
|
||
true | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters