Merge pull request #421 from crystal-ameba/add-binary-operator-parameter-name-rule

Add `Naming/BinaryOperatorParameterName` rule
This commit is contained in:
Sijawusz Pur Rahnama 2023-11-12 09:56:26 +01:00 committed by GitHub
commit 6caf24ad6d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 100 additions and 0 deletions

View File

@ -0,0 +1,50 @@
require "../../../spec_helper"
module Ameba::Rule::Naming
subject = BinaryOperatorParameterName.new
describe BinaryOperatorParameterName do
it "ignores `other` parameter name in binary method definitions" do
expect_no_issues subject, <<-CRYSTAL
def +(other); end
def -(other); end
def *(other); end
CRYSTAL
end
it "ignores binary method definitions with arity other than 1" do
expect_no_issues subject, <<-CRYSTAL
def +; end
def +(foo, bar); end
def -; end
def -(foo, bar); end
CRYSTAL
end
it "ignores non-binary method definitions" do
expect_no_issues subject, <<-CRYSTAL
def foo(bar); end
def bąk(genus); end
CRYSTAL
end
it "reports binary methods definitions with incorrectly named parameter" do
expect_issue subject, <<-CRYSTAL
def +(foo); end
# ^ error: When defining the `+` operator, name its argument `other`
def -(foo); end
# ^ error: When defining the `-` operator, name its argument `other`
def *(foo); end
# ^ error: When defining the `*` operator, name its argument `other`
CRYSTAL
end
it "ignores methods from #excluded_operators" do
subject.excluded_operators.each do |op|
expect_no_issues subject, <<-CRYSTAL
def #{op}(foo); end
CRYSTAL
end
end
end
end

View File

@ -0,0 +1,50 @@
module Ameba::Rule::Naming
# A rule that enforces that certain binary operator methods have
# their sole parameter named `other`.
#
# For example, this is considered valid:
#
# ```
# class Money
# def +(other)
# end
# end
# ```
#
# And this is invalid parameter name:
#
# ```
# class Money
# def +(amount)
# end
# end
# ```
#
# YAML configuration example:
#
# ```
# Naming/BinaryOperatorParameterName:
# Enabled: true
# ExcludedOperators: ["[]", "[]?", "[]=", "<<", "=~"]
# ```
class BinaryOperatorParameterName < Base
properties do
description "Enforces that certain binary operator methods have " \
"their sole parameter named `other`"
excluded_operators %w[[] []? []= << ` =~]
end
MSG = "When defining the `%s` operator, name its argument `other`"
def test(source, node : Crystal::Def)
name = node.name
return if name == "->" || name.in?(excluded_operators)
return if name.chars.any?(&.alphanumeric?)
return unless node.args.size == 1
return if (arg = node.args.first).name == "other"
issue_for arg, MSG % name
end
end
end